Merge remote-tracking branch 'upstream/master' into mpmcqueue

pull/19358/head
Yunjia Wang 6 years ago
commit e4adb6ac56
  1. 189
      CMakeLists.txt
  2. 262
      Makefile
  3. 8
      doc/environment_variables.md
  4. 5
      include/grpcpp/impl/codegen/call_op_set.h
  5. 11
      include/grpcpp/impl/codegen/server_callback.h
  6. 434
      src/core/ext/filters/client_channel/client_channel.cc
  7. 19
      src/core/ext/filters/client_channel/lb_policy.cc
  8. 8
      src/core/ext/filters/client_channel/lb_policy.h
  9. 9
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  10. 44
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  11. 24
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  12. 126
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  13. 105
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  14. 14
      src/core/ext/filters/client_channel/resolver.h
  15. 23
      src/core/ext/filters/client_channel/subchannel.cc
  16. 71
      src/core/ext/filters/client_channel/subchannel.h
  17. 45
      src/core/ext/filters/client_channel/subchannel_interface.h
  18. 28
      src/core/lib/gprpp/map.h
  19. 2
      src/core/lib/iomgr/call_combiner.cc
  20. 2
      src/core/lib/iomgr/call_combiner.h
  21. 5
      src/core/lib/iomgr/cfstream_handle.cc
  22. 4
      src/core/lib/iomgr/cfstream_handle.h
  23. 6
      src/core/lib/iomgr/ev_posix.cc
  24. 5
      src/core/lib/iomgr/ev_posix.h
  25. 4
      src/core/lib/iomgr/ev_windows.cc
  26. 2
      src/core/lib/iomgr/lockfree_event.cc
  27. 6
      src/core/lib/iomgr/port.h
  28. 11
      src/core/lib/iomgr/tcp_uv.cc
  29. 4
      src/core/lib/security/transport/security_handshaker.cc
  30. 52
      src/core/lib/slice/slice_buffer.cc
  31. 5
      src/core/lib/transport/metadata.cc
  32. 2
      src/core/lib/transport/transport.cc
  33. 10
      src/core/lib/transport/transport.h
  34. 3
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
  35. 5
      src/objective-c/GRPCClient/GRPCCallOptions.h
  36. 10
      src/objective-c/GRPCClient/GRPCCallOptions.m
  37. 2
      src/objective-c/GRPCClient/private/GRPCChannel.m
  38. 4
      src/objective-c/GRPCClient/private/GRPCChannelPool.m
  39. 10
      src/objective-c/GRPCClient/private/GRPCHost.m
  40. 4
      src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m
  41. 6
      src/objective-c/tests/InteropTests/InteropTests.h
  42. 190
      src/objective-c/tests/InteropTests/InteropTests.m
  43. 4
      src/objective-c/tests/InteropTests/InteropTestsRemote.m
  44. 383
      src/objective-c/tests/MacTests/StressTests.m
  45. 330
      src/objective-c/tests/UnitTests/APIv2Tests.m
  46. 28
      templates/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile.template
  47. 4
      test/core/bad_client/gen_build_yaml.py
  48. 4
      test/core/bad_client/generate_tests.bzl
  49. 41
      test/core/bad_client/tests/unknown_frame.cc
  50. 29
      test/core/gprpp/map_test.cc
  51. 2
      test/core/util/test_lb_policies.cc
  52. 3
      test/cpp/interop/interop_server.cc
  53. 79
      tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile
  54. 29
      tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh
  55. 24
      tools/run_tests/generated/sources_and_headers.json
  56. 22
      tools/run_tests/generated/tests.json
  57. 18
      tools/run_tests/run_tests.py

@ -441,17 +441,6 @@ add_dependencies(buildtests_c udp_server_test)
endif() endif()
add_dependencies(buildtests_c uri_parser_test) add_dependencies(buildtests_c uri_parser_test)
add_dependencies(buildtests_c public_headers_must_be_c89) 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)
add_dependencies(buildtests_c duplicate_header_bad_client_test)
add_dependencies(buildtests_c head_of_line_blocking_bad_client_test)
add_dependencies(buildtests_c headers_bad_client_test)
add_dependencies(buildtests_c initial_settings_frame_bad_client_test)
add_dependencies(buildtests_c large_metadata_bad_client_test)
add_dependencies(buildtests_c server_registered_method_bad_client_test)
add_dependencies(buildtests_c simple_request_bad_client_test)
add_dependencies(buildtests_c unknown_frame_bad_client_test)
add_dependencies(buildtests_c window_overflow_bad_client_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bad_ssl_cert_server) add_dependencies(buildtests_c bad_ssl_cert_server)
endif() endif()
@ -736,6 +725,17 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx writes_per_rpc_test) add_dependencies(buildtests_cxx writes_per_rpc_test)
endif() endif()
add_dependencies(buildtests_cxx xds_end2end_test) add_dependencies(buildtests_cxx xds_end2end_test)
add_dependencies(buildtests_cxx badreq_bad_client_test)
add_dependencies(buildtests_cxx connection_prefix_bad_client_test)
add_dependencies(buildtests_cxx duplicate_header_bad_client_test)
add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test)
add_dependencies(buildtests_cxx headers_bad_client_test)
add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test)
add_dependencies(buildtests_cxx large_metadata_bad_client_test)
add_dependencies(buildtests_cxx server_registered_method_bad_client_test)
add_dependencies(buildtests_cxx simple_request_bad_client_test)
add_dependencies(buildtests_cxx unknown_frame_bad_client_test)
add_dependencies(buildtests_cxx window_overflow_bad_client_test)
add_dependencies(buildtests_cxx resolver_component_test_unsecure) add_dependencies(buildtests_cxx resolver_component_test_unsecure)
add_dependencies(buildtests_cxx resolver_component_test) add_dependencies(buildtests_cxx resolver_component_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -5852,18 +5852,19 @@ target_include_directories(bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(bad_client_test PROPERTIES LINKER_LANGUAGE C)
# only use the flags for C++ source files
target_compile_options(bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
target_link_libraries(bad_client_test target_link_libraries(bad_client_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
@ -17072,6 +17073,8 @@ if (gRPC_BUILD_TESTS)
add_executable(badreq_bad_client_test add_executable(badreq_bad_client_test
test/core/bad_client/tests/badreq.cc test/core/bad_client/tests/badreq.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17086,28 +17089,32 @@ target_include_directories(badreq_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(badreq_bad_client_test target_link_libraries(badreq_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(badreq_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(badreq_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(connection_prefix_bad_client_test add_executable(connection_prefix_bad_client_test
test/core/bad_client/tests/connection_prefix.cc test/core/bad_client/tests/connection_prefix.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17122,28 +17129,32 @@ target_include_directories(connection_prefix_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(connection_prefix_bad_client_test target_link_libraries(connection_prefix_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(connection_prefix_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(connection_prefix_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(duplicate_header_bad_client_test add_executable(duplicate_header_bad_client_test
test/core/bad_client/tests/duplicate_header.cc test/core/bad_client/tests/duplicate_header.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17158,28 +17169,32 @@ target_include_directories(duplicate_header_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(duplicate_header_bad_client_test target_link_libraries(duplicate_header_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(duplicate_header_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(duplicate_header_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(head_of_line_blocking_bad_client_test add_executable(head_of_line_blocking_bad_client_test
test/core/bad_client/tests/head_of_line_blocking.cc test/core/bad_client/tests/head_of_line_blocking.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17194,28 +17209,32 @@ target_include_directories(head_of_line_blocking_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(head_of_line_blocking_bad_client_test target_link_libraries(head_of_line_blocking_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(head_of_line_blocking_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(head_of_line_blocking_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(headers_bad_client_test add_executable(headers_bad_client_test
test/core/bad_client/tests/headers.cc test/core/bad_client/tests/headers.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17230,28 +17249,32 @@ target_include_directories(headers_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(headers_bad_client_test target_link_libraries(headers_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(headers_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(headers_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(initial_settings_frame_bad_client_test add_executable(initial_settings_frame_bad_client_test
test/core/bad_client/tests/initial_settings_frame.cc test/core/bad_client/tests/initial_settings_frame.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17266,28 +17289,32 @@ target_include_directories(initial_settings_frame_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(initial_settings_frame_bad_client_test target_link_libraries(initial_settings_frame_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(initial_settings_frame_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(initial_settings_frame_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(large_metadata_bad_client_test add_executable(large_metadata_bad_client_test
test/core/bad_client/tests/large_metadata.cc test/core/bad_client/tests/large_metadata.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17302,28 +17329,32 @@ target_include_directories(large_metadata_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(large_metadata_bad_client_test target_link_libraries(large_metadata_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(large_metadata_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(large_metadata_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(server_registered_method_bad_client_test add_executable(server_registered_method_bad_client_test
test/core/bad_client/tests/server_registered_method.cc test/core/bad_client/tests/server_registered_method.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17338,28 +17369,32 @@ target_include_directories(server_registered_method_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(server_registered_method_bad_client_test target_link_libraries(server_registered_method_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(server_registered_method_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(server_registered_method_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(simple_request_bad_client_test add_executable(simple_request_bad_client_test
test/core/bad_client/tests/simple_request.cc test/core/bad_client/tests/simple_request.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17374,28 +17409,32 @@ target_include_directories(simple_request_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(simple_request_bad_client_test target_link_libraries(simple_request_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(simple_request_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(simple_request_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(unknown_frame_bad_client_test add_executable(unknown_frame_bad_client_test
test/core/bad_client/tests/unknown_frame.cc test/core/bad_client/tests/unknown_frame.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17410,28 +17449,32 @@ target_include_directories(unknown_frame_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(unknown_frame_bad_client_test target_link_libraries(unknown_frame_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(unknown_frame_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(unknown_frame_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(window_overflow_bad_client_test add_executable(window_overflow_bad_client_test
test/core/bad_client/tests/window_overflow.cc test/core/bad_client/tests/window_overflow.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -17446,22 +17489,24 @@ target_include_directories(window_overflow_bad_client_test
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_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(window_overflow_bad_client_test target_link_libraries(window_overflow_bad_client_test
${_gRPC_SSL_LIBRARIES} ${_gRPC_SSL_LIBRARIES}
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
bad_client_test bad_client_test
grpc_test_util_unsecure grpc_test_util_unsecure
grpc_unsecure grpc_unsecure
gpr gpr
${_gRPC_GFLAGS_LIBRARIES}
) )
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(window_overflow_bad_client_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(window_overflow_bad_client_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)

@ -1406,7 +1406,7 @@ plugins: $(PROTOC_PLUGINS)
privatelibs: privatelibs_c privatelibs_cxx privatelibs: privatelibs_c privatelibs_cxx
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 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_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: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc
pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc
@ -1416,9 +1416,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc
pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
ifeq ($(EMBED_OPENSSL),true) ifeq ($(EMBED_OPENSSL),true)
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 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 $(LIBDIR)/$(CONFIG)/libbad_client_test.a
else else
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 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 $(LIBDIR)/$(CONFIG)/libbad_client_test.a
endif endif
@ -1557,17 +1557,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/udp_server_test \
$(BINDIR)/$(CONFIG)/uri_parser_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \
$(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \
$(BINDIR)/$(CONFIG)/bad_ssl_cert_server \ $(BINDIR)/$(CONFIG)/bad_ssl_cert_server \
$(BINDIR)/$(CONFIG)/bad_ssl_cert_test \ $(BINDIR)/$(CONFIG)/bad_ssl_cert_test \
$(BINDIR)/$(CONFIG)/h2_census_test \ $(BINDIR)/$(CONFIG)/h2_census_test \
@ -1764,6 +1753,17 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/boringssl_ssl_test \ $(BINDIR)/$(CONFIG)/boringssl_ssl_test \
$(BINDIR)/$(CONFIG)/boringssl_crypto_test \ $(BINDIR)/$(CONFIG)/boringssl_crypto_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \
$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \
$(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_test \
$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \
@ -1912,6 +1912,17 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \
$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \
$(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_test \
$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \
@ -2180,28 +2191,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 )
$(E) "[RUN] Testing public_headers_must_be_c89" $(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 ) $(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"
$(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing connection_prefix_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing duplicate_header_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing head_of_line_blocking_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing headers_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing initial_settings_frame_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing large_metadata_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing server_registered_method_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing simple_request_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/simple_request_bad_client_test || ( echo test simple_request_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing unknown_frame_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing window_overflow_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test || ( echo test window_overflow_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing bad_ssl_cert_test" $(E) "[RUN] Testing bad_ssl_cert_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_ssl_cert_test || ( echo test bad_ssl_cert_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bad_ssl_cert_test || ( echo test bad_ssl_cert_test failed ; exit 1 )
@ -2456,6 +2445,28 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
$(E) "[RUN] Testing xds_end2end_test" $(E) "[RUN] Testing xds_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing badreq_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing connection_prefix_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing duplicate_header_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing head_of_line_blocking_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing headers_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing initial_settings_frame_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing large_metadata_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing server_registered_method_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing simple_request_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/simple_request_bad_client_test || ( echo test simple_request_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing unknown_frame_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing window_overflow_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test || ( echo test window_overflow_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing resolver_component_tests_runner_invoker_unsecure" $(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 ) $(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" $(E) "[RUN] Testing resolver_component_tests_runner_invoker"
@ -8549,7 +8560,7 @@ endif
LIBBAD_CLIENT_TEST_SRC = \ LIBBAD_CLIENT_TEST_SRC = \
test/core/bad_client/bad_client.cc \ test/core/bad_client/bad_client.cc \
PUBLIC_HEADERS_C += \ PUBLIC_HEADERS_CXX += \
LIBBAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBAD_CLIENT_TEST_SRC)))) LIBBAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBAD_CLIENT_TEST_SRC))))
@ -8563,8 +8574,16 @@ $(LIBDIR)/$(CONFIG)/libbad_client_test.a: openssl_dep_error
else 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)/libbad_client_test.a: protobuf_dep_error
$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBBAD_CLIENT_TEST_OBJS) else
$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBAD_CLIENT_TEST_OBJS)
$(E) "[AR] Creating $@" $(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a
@ -8576,6 +8595,8 @@ endif
endif
endif endif
ifneq ($(NO_SECURE),true) ifneq ($(NO_SECURE),true)
@ -20350,10 +20371,21 @@ BADREQ_BAD_CLIENT_TEST_SRC = \
BADREQ_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BADREQ_BAD_CLIENT_TEST_SRC)))) 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.a
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)/badreq_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test
endif
$(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 $(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
@ -20370,10 +20402,21 @@ CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC = \
CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/connection_prefix_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
endif
$(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 $(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
@ -20390,10 +20433,21 @@ DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \
DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/duplicate_header_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test
endif
$(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 $(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
@ -20410,10 +20464,21 @@ 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)))) 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.a
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)/head_of_line_blocking_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test
endif
$(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 $(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
@ -20430,10 +20495,21 @@ HEADERS_BAD_CLIENT_TEST_SRC = \
HEADERS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/headers_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test
endif
$(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 $(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
@ -20450,10 +20526,21 @@ 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)))) 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.a
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)/initial_settings_frame_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
endif
$(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 $(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
@ -20470,10 +20557,21 @@ LARGE_METADATA_BAD_CLIENT_TEST_SRC = \
LARGE_METADATA_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/large_metadata_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test
endif
$(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 $(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
@ -20490,10 +20588,21 @@ 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)))) 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.a
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test
endif
$(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 $(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
@ -20510,10 +20619,21 @@ SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC = \
SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/simple_request_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test
endif
$(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 $(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
@ -20530,10 +20650,21 @@ UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC = \
UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/unknown_frame_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
endif
$(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 $(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
@ -20550,10 +20681,21 @@ WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC = \
WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(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.a
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)/window_overflow_bad_client_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(PROTOBUF_DEP) $(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 $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(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.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test $(Q) $(LDXX) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test
endif
$(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 $(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

@ -39,7 +39,6 @@ some configuration as environment variables that can be set.
gRPC C core is processing requests via debug logs. Available tracers include: gRPC C core is processing requests via debug logs. Available tracers include:
- api - traces api calls to the C core - api - traces api calls to the C core
- bdp_estimator - traces behavior of bdp estimation logic - 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 - call_error - traces the possible errors contributing to final call status
- cares_resolver - traces operations of the c-ares based DNS resolver - cares_resolver - traces operations of the c-ares based DNS resolver
- cares_address_sorting - traces operations of the c-ares based DNS - cares_address_sorting - traces operations of the c-ares based DNS
@ -52,9 +51,6 @@ some configuration as environment variables that can be set.
- connectivity_state - traces connectivity state changes to channels - connectivity_state - traces connectivity state changes to channels
- cronet - traces state in the cronet transport engine - cronet - traces state in the cronet transport engine
- executor - traces grpc's internal thread pool ('the executor') - 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
traces epoll-fd creation/close calls for epollex polling engine
- glb - traces the grpclb load balancer - glb - traces the grpclb load balancer
- handshaker - traces handshaking state - handshaker - traces handshaking state
- health_check_client - traces health checking client code - health_check_client - traces health checking client code
@ -86,7 +82,11 @@ some configuration as environment variables that can be set.
- alarm_refcount - refcounting traces for grpc_alarm structure - alarm_refcount - refcounting traces for grpc_alarm structure
- metadata - tracks creation and mutation of metadata - metadata - tracks creation and mutation of metadata
- combiner - traces combiner lock state - combiner - traces combiner lock state
- call_combiner - traces call combiner state
- closure - tracks closure creation, scheduling, and completion - closure - tracks closure creation, scheduling, and completion
- fd_trace - traces fd create(), shutdown() and close() calls for channel fds.
Also traces epoll fd create()/close() calls in epollex polling engine
traces epoll-fd creation/close calls for epollex polling engine
- pending_tags - traces still-in-progress tags on completion queues - pending_tags - traces still-in-progress tags on completion queues
- polling - traces the selected polling engine - polling - traces the selected polling engine
- polling_api - traces the api calls to polling engine - polling_api - traces the api calls to polling engine

@ -188,11 +188,6 @@ class WriteOptions {
/// \sa GRPC_WRITE_LAST_MESSAGE /// \sa GRPC_WRITE_LAST_MESSAGE
bool is_last_message() const { return last_message_; } bool is_last_message() const { return last_message_; }
WriteOptions& operator=(const WriteOptions& rhs) {
flags_ = rhs.flags_;
return *this;
}
private: private:
void SetBit(const uint32_t mask) { flags_ |= mask; } void SetBit(const uint32_t mask) { flags_ |= mask; }

@ -348,7 +348,8 @@ class ServerBidiReactor : public internal::ServerReactor {
private: private:
friend class ServerCallbackReaderWriter<Request, Response>; friend class ServerCallbackReaderWriter<Request, Response>;
void BindStream(ServerCallbackReaderWriter<Request, Response>* stream) { virtual void BindStream(
ServerCallbackReaderWriter<Request, Response>* stream) {
stream_ = stream; stream_ = stream;
} }
@ -382,7 +383,9 @@ class ServerReadReactor : public internal::ServerReactor {
private: private:
friend class ServerCallbackReader<Request>; friend class ServerCallbackReader<Request>;
void BindReader(ServerCallbackReader<Request>* reader) { reader_ = reader; } virtual void BindReader(ServerCallbackReader<Request>* reader) {
reader_ = reader;
}
ServerCallbackReader<Request>* reader_; ServerCallbackReader<Request>* reader_;
}; };
@ -424,7 +427,9 @@ class ServerWriteReactor : public internal::ServerReactor {
private: private:
friend class ServerCallbackWriter<Response>; friend class ServerCallbackWriter<Response>;
void BindWriter(ServerCallbackWriter<Response>* writer) { writer_ = writer; } virtual void BindWriter(ServerCallbackWriter<Response>* writer) {
writer_ = writer;
}
ServerCallbackWriter<Response>* writer_; ServerCallbackWriter<Response>* writer_;
}; };

@ -147,6 +147,9 @@ class ChannelData {
return service_config_; return service_config_;
} }
RefCountedPtr<ConnectedSubchannel> GetConnectedSubchannelInDataPlane(
SubchannelInterface* subchannel) const;
grpc_connectivity_state CheckConnectivityState(bool try_to_connect); grpc_connectivity_state CheckConnectivityState(bool try_to_connect);
void AddExternalConnectivityWatcher(grpc_polling_entity pollent, void AddExternalConnectivityWatcher(grpc_polling_entity pollent,
grpc_connectivity_state* state, grpc_connectivity_state* state,
@ -161,9 +164,9 @@ class ChannelData {
} }
private: private:
class SubchannelWrapper;
class ConnectivityStateAndPickerSetter; class ConnectivityStateAndPickerSetter;
class ServiceConfigSetter; class ServiceConfigSetter;
class GrpcSubchannel;
class ClientChannelControlHelper; class ClientChannelControlHelper;
class ExternalConnectivityWatcher { class ExternalConnectivityWatcher {
@ -262,7 +265,14 @@ class ChannelData {
UniquePtr<char> health_check_service_name_; UniquePtr<char> health_check_service_name_;
RefCountedPtr<ServiceConfig> saved_service_config_; RefCountedPtr<ServiceConfig> saved_service_config_;
bool received_first_resolver_result_ = false; bool received_first_resolver_result_ = false;
// The number of SubchannelWrapper instances referencing a given Subchannel.
Map<Subchannel*, int> subchannel_refcount_map_; Map<Subchannel*, int> subchannel_refcount_map_;
// Pending ConnectedSubchannel updates for each SubchannelWrapper.
// Updates are queued here in the control plane combiner and then applied
// in the data plane combiner when the picker is updated.
Map<RefCountedPtr<SubchannelWrapper>, RefCountedPtr<ConnectedSubchannel>,
RefCountedPtrLess<SubchannelWrapper>>
pending_subchannel_updates_;
// //
// Fields accessed from both data plane and control plane combiners. // Fields accessed from both data plane and control plane combiners.
@ -706,6 +716,247 @@ class CallData {
grpc_metadata_batch send_trailing_metadata_; grpc_metadata_batch send_trailing_metadata_;
}; };
//
// ChannelData::SubchannelWrapper
//
// This class is a wrapper for Subchannel that hides details of the
// channel's implementation (such as the health check service name and
// connected subchannel) from the LB policy API.
//
// Note that no synchronization is needed here, because even if the
// underlying subchannel is shared between channels, this wrapper will only
// be used within one channel, so it will always be synchronized by the
// control plane combiner.
class ChannelData::SubchannelWrapper : public SubchannelInterface {
public:
SubchannelWrapper(ChannelData* chand, Subchannel* subchannel,
UniquePtr<char> health_check_service_name)
: SubchannelInterface(&grpc_client_channel_routing_trace),
chand_(chand),
subchannel_(subchannel),
health_check_service_name_(std::move(health_check_service_name)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: creating subchannel wrapper %p for subchannel %p",
chand, this, subchannel_);
}
GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "SubchannelWrapper");
auto* subchannel_node = subchannel_->channelz_node();
if (subchannel_node != nullptr) {
intptr_t subchannel_uuid = subchannel_node->uuid();
auto it = chand_->subchannel_refcount_map_.find(subchannel_);
if (it == chand_->subchannel_refcount_map_.end()) {
chand_->channelz_node_->AddChildSubchannel(subchannel_uuid);
it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first;
}
++it->second;
}
}
~SubchannelWrapper() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: destroying subchannel wrapper %p for subchannel %p",
chand_, this, subchannel_);
}
auto* subchannel_node = subchannel_->channelz_node();
if (subchannel_node != nullptr) {
intptr_t subchannel_uuid = subchannel_node->uuid();
auto it = chand_->subchannel_refcount_map_.find(subchannel_);
GPR_ASSERT(it != chand_->subchannel_refcount_map_.end());
--it->second;
if (it->second == 0) {
chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid);
chand_->subchannel_refcount_map_.erase(it);
}
}
GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB");
GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "SubchannelWrapper");
}
grpc_connectivity_state CheckConnectivityState() override {
RefCountedPtr<ConnectedSubchannel> connected_subchannel;
grpc_connectivity_state connectivity_state =
subchannel_->CheckConnectivityState(health_check_service_name_.get(),
&connected_subchannel);
MaybeUpdateConnectedSubchannel(std::move(connected_subchannel));
return connectivity_state;
}
void WatchConnectivityState(
grpc_connectivity_state initial_state,
UniquePtr<ConnectivityStateWatcherInterface> watcher) override {
auto& watcher_wrapper = watcher_map_[watcher.get()];
GPR_ASSERT(watcher_wrapper == nullptr);
watcher_wrapper = New<WatcherWrapper>(
std::move(watcher), Ref(DEBUG_LOCATION, "WatcherWrapper"));
subchannel_->WatchConnectivityState(
initial_state,
UniquePtr<char>(gpr_strdup(health_check_service_name_.get())),
OrphanablePtr<Subchannel::ConnectivityStateWatcherInterface>(
watcher_wrapper));
}
void CancelConnectivityStateWatch(
ConnectivityStateWatcherInterface* watcher) override {
auto it = watcher_map_.find(watcher);
GPR_ASSERT(it != watcher_map_.end());
subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(),
it->second);
watcher_map_.erase(it);
}
void AttemptToConnect() override { subchannel_->AttemptToConnect(); }
void ResetBackoff() override { subchannel_->ResetBackoff(); }
const grpc_channel_args* channel_args() override {
return subchannel_->channel_args();
}
// Caller must be holding the control-plane combiner.
ConnectedSubchannel* connected_subchannel() const {
return connected_subchannel_.get();
}
// Caller must be holding the data-plane combiner.
ConnectedSubchannel* connected_subchannel_in_data_plane() const {
return connected_subchannel_in_data_plane_.get();
}
void set_connected_subchannel_in_data_plane(
RefCountedPtr<ConnectedSubchannel> connected_subchannel) {
connected_subchannel_in_data_plane_ = std::move(connected_subchannel);
}
private:
// Subchannel and SubchannelInterface have different interfaces for
// their respective ConnectivityStateWatcherInterface classes.
// The one in Subchannel updates the ConnectedSubchannel along with
// the state, whereas the one in SubchannelInterface does not expose
// the ConnectedSubchannel.
//
// This wrapper provides a bridge between the two. It implements
// Subchannel::ConnectivityStateWatcherInterface and wraps
// the instance of SubchannelInterface::ConnectivityStateWatcherInterface
// that was passed in by the LB policy. We pass an instance of this
// class to the underlying Subchannel, and when we get updates from
// the subchannel, we pass those on to the wrapped watcher to return
// the update to the LB policy. This allows us to set the connected
// subchannel before passing the result back to the LB policy.
class WatcherWrapper : public Subchannel::ConnectivityStateWatcherInterface {
public:
WatcherWrapper(
UniquePtr<SubchannelInterface::ConnectivityStateWatcherInterface>
watcher,
RefCountedPtr<SubchannelWrapper> parent)
: watcher_(std::move(watcher)), parent_(std::move(parent)) {}
~WatcherWrapper() { parent_.reset(DEBUG_LOCATION, "WatcherWrapper"); }
void Orphan() override { Unref(); }
void OnConnectivityStateChange(
grpc_connectivity_state new_state,
RefCountedPtr<ConnectedSubchannel> connected_subchannel) override {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: connectivity change for subchannel wrapper %p "
"subchannel %p (connected_subchannel=%p state=%s); "
"hopping into combiner",
parent_->chand_, parent_.get(), parent_->subchannel_,
connected_subchannel.get(),
grpc_connectivity_state_name(new_state));
}
// Will delete itself.
New<Updater>(Ref(), new_state, std::move(connected_subchannel));
}
grpc_pollset_set* interested_parties() override {
return watcher_->interested_parties();
}
private:
class Updater {
public:
Updater(RefCountedPtr<WatcherWrapper> parent,
grpc_connectivity_state new_state,
RefCountedPtr<ConnectedSubchannel> connected_subchannel)
: parent_(std::move(parent)),
state_(new_state),
connected_subchannel_(std::move(connected_subchannel)) {
GRPC_CLOSURE_INIT(
&closure_, ApplyUpdateInControlPlaneCombiner, this,
grpc_combiner_scheduler(parent_->parent_->chand_->combiner_));
GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE);
}
private:
static void ApplyUpdateInControlPlaneCombiner(void* arg,
grpc_error* error) {
Updater* self = static_cast<Updater*>(arg);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: processing connectivity change in combiner "
"for subchannel wrapper %p subchannel %p "
"(connected_subchannel=%p state=%s)",
self->parent_->parent_->chand_, self->parent_->parent_.get(),
self->parent_->parent_->subchannel_,
self->connected_subchannel_.get(),
grpc_connectivity_state_name(self->state_));
}
self->parent_->parent_->MaybeUpdateConnectedSubchannel(
std::move(self->connected_subchannel_));
self->parent_->watcher_->OnConnectivityStateChange(self->state_);
Delete(self);
}
RefCountedPtr<WatcherWrapper> parent_;
grpc_connectivity_state state_;
RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
grpc_closure closure_;
};
UniquePtr<SubchannelInterface::ConnectivityStateWatcherInterface> watcher_;
RefCountedPtr<SubchannelWrapper> parent_;
};
void MaybeUpdateConnectedSubchannel(
RefCountedPtr<ConnectedSubchannel> connected_subchannel) {
// Update the connected subchannel only if the channel is not shutting
// down. This is because once the channel is shutting down, we
// ignore picker updates from the LB policy, which means that
// ConnectivityStateAndPickerSetter will never process the entries
// in chand_->pending_subchannel_updates_. So we don't want to add
// entries there that will never be processed, since that would
// leave dangling refs to the channel and prevent its destruction.
grpc_error* disconnect_error = chand_->disconnect_error();
if (disconnect_error != GRPC_ERROR_NONE) return;
// Not shutting down, so do the update.
if (connected_subchannel_ != connected_subchannel) {
connected_subchannel_ = std::move(connected_subchannel);
// Record the new connected subchannel so that it can be updated
// in the data plane combiner the next time the picker is updated.
chand_->pending_subchannel_updates_[Ref(
DEBUG_LOCATION, "ConnectedSubchannelUpdate")] = connected_subchannel_;
}
}
ChannelData* chand_;
Subchannel* subchannel_;
UniquePtr<char> health_check_service_name_;
// Maps from the address of the watcher passed to us by the LB policy
// to the address of the WrapperWatcher that we passed to the underlying
// subchannel. This is needed so that when the LB policy calls
// CancelConnectivityStateWatch() with its watcher, we know the
// corresponding WrapperWatcher to cancel on the underlying subchannel.
Map<ConnectivityStateWatcherInterface*, WatcherWrapper*> watcher_map_;
// To be accessed only in the control plane combiner.
RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
// To be accessed only in the data plane combiner.
RefCountedPtr<ConnectedSubchannel> connected_subchannel_in_data_plane_;
};
// //
// ChannelData::ConnectivityStateAndPickerSetter // ChannelData::ConnectivityStateAndPickerSetter
// //
@ -729,10 +980,13 @@ class ChannelData::ConnectivityStateAndPickerSetter {
grpc_slice_from_static_string( grpc_slice_from_static_string(
GetChannelConnectivityStateChangeString(state))); GetChannelConnectivityStateChangeString(state)));
} }
// Grab any pending subchannel updates.
pending_subchannel_updates_ =
std::move(chand_->pending_subchannel_updates_);
// Bounce into the data plane combiner to reset the picker. // Bounce into the data plane combiner to reset the picker.
GRPC_CHANNEL_STACK_REF(chand->owning_stack_, GRPC_CHANNEL_STACK_REF(chand->owning_stack_,
"ConnectivityStateAndPickerSetter"); "ConnectivityStateAndPickerSetter");
GRPC_CLOSURE_INIT(&closure_, SetPicker, this, GRPC_CLOSURE_INIT(&closure_, SetPickerInDataPlane, this,
grpc_combiner_scheduler(chand->data_plane_combiner_)); grpc_combiner_scheduler(chand->data_plane_combiner_));
GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE);
} }
@ -755,16 +1009,38 @@ class ChannelData::ConnectivityStateAndPickerSetter {
GPR_UNREACHABLE_CODE(return "UNKNOWN"); GPR_UNREACHABLE_CODE(return "UNKNOWN");
} }
static void SetPicker(void* arg, grpc_error* ignored) { static void SetPickerInDataPlane(void* arg, grpc_error* ignored) {
auto* self = static_cast<ConnectivityStateAndPickerSetter*>(arg); auto* self = static_cast<ConnectivityStateAndPickerSetter*>(arg);
// Update picker. // Handle subchannel updates.
self->chand_->picker_ = std::move(self->picker_); for (auto& p : self->pending_subchannel_updates_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO,
"chand=%p: updating subchannel wrapper %p data plane "
"connected_subchannel to %p",
self->chand_, p.first.get(), p.second.get());
}
p.first->set_connected_subchannel_in_data_plane(std::move(p.second));
}
// Swap out the picker. We hang on to the old picker so that it can
// be deleted in the control-plane combiner, since that's where we need
// to unref the subchannel wrappers that are reffed by the picker.
self->picker_.swap(self->chand_->picker_);
// Re-process queued picks. // Re-process queued picks.
for (QueuedPick* pick = self->chand_->queued_picks_; pick != nullptr; for (QueuedPick* pick = self->chand_->queued_picks_; pick != nullptr;
pick = pick->next) { pick = pick->next) {
CallData::StartPickLocked(pick->elem, GRPC_ERROR_NONE); CallData::StartPickLocked(pick->elem, GRPC_ERROR_NONE);
} }
// Clean up. // Pop back into the control plane combiner to delete ourself, so
// that we make sure to unref subchannel wrappers there. This
// includes both the ones reffed by the old picker (now stored in
// self->picker_) and the ones in self->pending_subchannel_updates_.
GRPC_CLOSURE_INIT(&self->closure_, CleanUpInControlPlane, self,
grpc_combiner_scheduler(self->chand_->combiner_));
GRPC_CLOSURE_SCHED(&self->closure_, GRPC_ERROR_NONE);
}
static void CleanUpInControlPlane(void* arg, grpc_error* ignored) {
auto* self = static_cast<ConnectivityStateAndPickerSetter*>(arg);
GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_,
"ConnectivityStateAndPickerSetter"); "ConnectivityStateAndPickerSetter");
Delete(self); Delete(self);
@ -772,6 +1048,9 @@ class ChannelData::ConnectivityStateAndPickerSetter {
ChannelData* chand_; ChannelData* chand_;
UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker_; UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker_;
Map<RefCountedPtr<SubchannelWrapper>, RefCountedPtr<ConnectedSubchannel>,
RefCountedPtrLess<SubchannelWrapper>>
pending_subchannel_updates_;
grpc_closure closure_; grpc_closure closure_;
}; };
@ -946,89 +1225,6 @@ void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked(
&self->chand_->state_tracker_, self->state_, &self->my_closure_); &self->chand_->state_tracker_, self->state_, &self->my_closure_);
} }
//
// ChannelData::GrpcSubchannel
//
// This class is a wrapper for Subchannel that hides details of the
// channel's implementation (such as the health check service name) from
// the LB policy API.
//
// Note that no synchronization is needed here, because even if the
// underlying subchannel is shared between channels, this wrapper will only
// be used within one channel, so it will always be synchronized by the
// control plane combiner.
class ChannelData::GrpcSubchannel : public SubchannelInterface {
public:
GrpcSubchannel(ChannelData* chand, Subchannel* subchannel,
UniquePtr<char> health_check_service_name)
: chand_(chand),
subchannel_(subchannel),
health_check_service_name_(std::move(health_check_service_name)) {
GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "GrpcSubchannel");
auto* subchannel_node = subchannel_->channelz_node();
if (subchannel_node != nullptr) {
intptr_t subchannel_uuid = subchannel_node->uuid();
auto it = chand_->subchannel_refcount_map_.find(subchannel_);
if (it == chand_->subchannel_refcount_map_.end()) {
chand_->channelz_node_->AddChildSubchannel(subchannel_uuid);
it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first;
}
++it->second;
}
}
~GrpcSubchannel() {
auto* subchannel_node = subchannel_->channelz_node();
if (subchannel_node != nullptr) {
intptr_t subchannel_uuid = subchannel_node->uuid();
auto it = chand_->subchannel_refcount_map_.find(subchannel_);
GPR_ASSERT(it != chand_->subchannel_refcount_map_.end());
--it->second;
if (it->second == 0) {
chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid);
chand_->subchannel_refcount_map_.erase(it);
}
}
GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB");
GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "GrpcSubchannel");
}
grpc_connectivity_state CheckConnectivityState(
RefCountedPtr<ConnectedSubchannelInterface>* connected_subchannel)
override {
RefCountedPtr<ConnectedSubchannel> tmp;
auto retval = subchannel_->CheckConnectivityState(
health_check_service_name_.get(), &tmp);
*connected_subchannel = std::move(tmp);
return retval;
}
void WatchConnectivityState(
grpc_connectivity_state initial_state,
UniquePtr<ConnectivityStateWatcher> watcher) override {
subchannel_->WatchConnectivityState(
initial_state,
UniquePtr<char>(gpr_strdup(health_check_service_name_.get())),
std::move(watcher));
}
void CancelConnectivityStateWatch(
ConnectivityStateWatcher* watcher) override {
subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(),
watcher);
}
void AttemptToConnect() override { subchannel_->AttemptToConnect(); }
void ResetBackoff() override { subchannel_->ResetBackoff(); }
private:
ChannelData* chand_;
Subchannel* subchannel_;
UniquePtr<char> health_check_service_name_;
};
// //
// ChannelData::ClientChannelControlHelper // ChannelData::ClientChannelControlHelper
// //
@ -1066,8 +1262,8 @@ class ChannelData::ClientChannelControlHelper
chand_->client_channel_factory_->CreateSubchannel(new_args); chand_->client_channel_factory_->CreateSubchannel(new_args);
grpc_channel_args_destroy(new_args); grpc_channel_args_destroy(new_args);
if (subchannel == nullptr) return nullptr; if (subchannel == nullptr) return nullptr;
return MakeRefCounted<GrpcSubchannel>(chand_, subchannel, return MakeRefCounted<SubchannelWrapper>(
std::move(health_check_service_name)); chand_, subchannel, std::move(health_check_service_name));
} }
grpc_channel* CreateChannel(const char* target, grpc_channel* CreateChannel(const char* target,
@ -1078,8 +1274,7 @@ class ChannelData::ClientChannelControlHelper
void UpdateState( void UpdateState(
grpc_connectivity_state state, grpc_connectivity_state state,
UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker) override { UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker) override {
grpc_error* disconnect_error = grpc_error* disconnect_error = chand_->disconnect_error();
chand_->disconnect_error_.Load(MemoryOrder::ACQUIRE);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
const char* extra = disconnect_error == GRPC_ERROR_NONE const char* extra = disconnect_error == GRPC_ERROR_NONE
? "" ? ""
@ -1180,6 +1375,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
interested_parties_(grpc_pollset_set_create()), interested_parties_(grpc_pollset_set_create()),
subchannel_pool_(GetSubchannelPool(args->channel_args)), subchannel_pool_(GetSubchannelPool(args->channel_args)),
disconnect_error_(GRPC_ERROR_NONE) { disconnect_error_(GRPC_ERROR_NONE) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p: creating client_channel for channel stack %p",
this, owning_stack_);
}
// Initialize data members. // Initialize data members.
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
"client_channel"); "client_channel");
@ -1236,10 +1435,8 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
std::move(target_uri), ProcessResolverResultLocked, this, error)); std::move(target_uri), ProcessResolverResultLocked, this, error));
grpc_channel_args_destroy(new_args); grpc_channel_args_destroy(new_args);
if (*error != GRPC_ERROR_NONE) { if (*error != GRPC_ERROR_NONE) {
// Orphan the resolving LB policy and flush the exec_ctx to ensure // Before we return, shut down the resolving LB policy, which destroys
// that it finishes shutting down. This ensures that if we are // the ClientChannelControlHelper and therefore unrefs the channel stack.
// 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 // TODO(roth): This is not a complete solution, because it only
// catches the case where channel stack initialization fails in this // catches the case where channel stack initialization fails in this
// particular filter. If there is a failure in a different filter, we // particular filter. If there is a failure in a different filter, we
@ -1247,7 +1444,6 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
// in practice, there are no other filters that can cause failures in // in practice, there are no other filters that can cause failures in
// channel stack initialization, so this works for now. // channel stack initialization, so this works for now.
resolving_lb_policy_.reset(); resolving_lb_policy_.reset();
ExecCtx::Get()->Flush();
} else { } else {
grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(),
interested_parties_); interested_parties_);
@ -1259,6 +1455,9 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
} }
ChannelData::~ChannelData() { ChannelData::~ChannelData() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, "chand=%p: destroying channel", this);
}
if (resolving_lb_policy_ != nullptr) { if (resolving_lb_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(), grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(),
interested_parties_); interested_parties_);
@ -1444,9 +1643,13 @@ grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) {
} }
LoadBalancingPolicy::PickResult result = LoadBalancingPolicy::PickResult result =
picker_->Pick(LoadBalancingPolicy::PickArgs()); picker_->Pick(LoadBalancingPolicy::PickArgs());
if (result.connected_subchannel != nullptr) { ConnectedSubchannel* connected_subchannel = nullptr;
ConnectedSubchannel* connected_subchannel = if (result.subchannel != nullptr) {
static_cast<ConnectedSubchannel*>(result.connected_subchannel.get()); SubchannelWrapper* subchannel =
static_cast<SubchannelWrapper*>(result.subchannel.get());
connected_subchannel = subchannel->connected_subchannel();
}
if (connected_subchannel != nullptr) {
connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack); connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack);
} else { } else {
if (result.error == GRPC_ERROR_NONE) { if (result.error == GRPC_ERROR_NONE) {
@ -1489,6 +1692,10 @@ void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) {
} }
// Disconnect. // Disconnect.
if (op->disconnect_with_error != GRPC_ERROR_NONE) { if (op->disconnect_with_error != GRPC_ERROR_NONE) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO, "chand=%p: channel shut down from API: %s", chand,
grpc_error_string(op->disconnect_with_error));
}
grpc_error* error = GRPC_ERROR_NONE; grpc_error* error = GRPC_ERROR_NONE;
GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong( GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong(
&error, op->disconnect_with_error, MemoryOrder::ACQ_REL, &error, op->disconnect_with_error, MemoryOrder::ACQ_REL,
@ -1563,6 +1770,17 @@ void ChannelData::RemoveQueuedPick(QueuedPick* to_remove,
} }
} }
RefCountedPtr<ConnectedSubchannel>
ChannelData::GetConnectedSubchannelInDataPlane(
SubchannelInterface* subchannel) const {
SubchannelWrapper* subchannel_wrapper =
static_cast<SubchannelWrapper*>(subchannel);
ConnectedSubchannel* connected_subchannel =
subchannel_wrapper->connected_subchannel_in_data_plane();
if (connected_subchannel == nullptr) return nullptr;
return connected_subchannel->Ref();
}
void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) { void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) {
auto* chand = static_cast<ChannelData*>(arg); auto* chand = static_cast<ChannelData*>(arg);
if (chand->resolving_lb_policy_ != nullptr) { if (chand->resolving_lb_policy_ != nullptr) {
@ -3490,10 +3708,9 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) {
auto result = chand->picker()->Pick(pick_args); auto result = chand->picker()->Pick(pick_args);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " "chand=%p calld=%p: LB pick returned %s (subchannel=%p, error=%s)",
"error=%s)",
chand, calld, PickResultTypeName(result.type), chand, calld, PickResultTypeName(result.type),
result.connected_subchannel.get(), grpc_error_string(result.error)); result.subchannel.get(), grpc_error_string(result.error));
} }
switch (result.type) { switch (result.type) {
case LoadBalancingPolicy::PickResult::PICK_TRANSIENT_FAILURE: { case LoadBalancingPolicy::PickResult::PICK_TRANSIENT_FAILURE: {
@ -3535,11 +3752,16 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) {
break; break;
default: // PICK_COMPLETE default: // PICK_COMPLETE
// Handle drops. // Handle drops.
if (GPR_UNLIKELY(result.connected_subchannel == nullptr)) { if (GPR_UNLIKELY(result.subchannel == nullptr)) {
result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Call dropped by load balancing policy"); "Call dropped by load balancing policy");
} else {
// Grab a ref to the connected subchannel while we're still
// holding the data plane combiner.
calld->connected_subchannel_ =
chand->GetConnectedSubchannelInDataPlane(result.subchannel.get());
GPR_ASSERT(calld->connected_subchannel_ != nullptr);
} }
calld->connected_subchannel_ = std::move(result.connected_subchannel);
calld->lb_recv_trailing_metadata_ready_ = calld->lb_recv_trailing_metadata_ready_ =
result.recv_trailing_metadata_ready; result.recv_trailing_metadata_ready;
calld->lb_recv_trailing_metadata_ready_user_data_ = calld->lb_recv_trailing_metadata_ready_user_data_ =

@ -43,23 +43,8 @@ LoadBalancingPolicy::~LoadBalancingPolicy() {
} }
void LoadBalancingPolicy::Orphan() { void LoadBalancingPolicy::Orphan() {
// Invoke ShutdownAndUnrefLocked() inside of the combiner. ShutdownLocked();
// TODO(roth): Is this actually needed? We should already be in the Unref();
// 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<LoadBalancingPolicy*>(arg);
policy->ShutdownLocked();
policy->channel_control_helper_.reset();
policy->Unref();
} }
// //

@ -128,7 +128,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Used only if type is PICK_COMPLETE. Will be set to the selected /// Used only if type is PICK_COMPLETE. Will be set to the selected
/// subchannel, or nullptr if the LB policy decides to drop the call. /// subchannel, or nullptr if the LB policy decides to drop the call.
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel; RefCountedPtr<SubchannelInterface> subchannel;
/// Used only if type is PICK_TRANSIENT_FAILURE. /// Used only if type is PICK_TRANSIENT_FAILURE.
/// Error to be set when returning a transient failure. /// Error to be set when returning a transient failure.
@ -282,6 +282,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
grpc_pollset_set* interested_parties() const { return interested_parties_; } grpc_pollset_set* interested_parties() const { return interested_parties_; }
// Note: This must be invoked while holding the combiner.
void Orphan() override; void Orphan() override;
// A picker that returns PICK_QUEUE for all picks. // A picker that returns PICK_QUEUE for all picks.
@ -292,6 +293,8 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
explicit QueuePicker(RefCountedPtr<LoadBalancingPolicy> parent) explicit QueuePicker(RefCountedPtr<LoadBalancingPolicy> parent)
: parent_(std::move(parent)) {} : parent_(std::move(parent)) {}
~QueuePicker() { parent_.reset(DEBUG_LOCATION, "QueuePicker"); }
PickResult Pick(PickArgs args) override; PickResult Pick(PickArgs args) override;
private: private:
@ -320,7 +323,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
// Note: LB policies MUST NOT call any method on the helper from their // Note: LB policies MUST NOT call any method on the helper from their
// constructor. // constructor.
// Note: This will return null after ShutdownLocked() has been called.
ChannelControlHelper* channel_control_helper() const { ChannelControlHelper* channel_control_helper() const {
return channel_control_helper_.get(); return channel_control_helper_.get();
} }
@ -329,8 +331,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
virtual void ShutdownLocked() GRPC_ABSTRACT; virtual void ShutdownLocked() GRPC_ABSTRACT;
private: private:
static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored);
/// Combiner under which LB policy actions take place. /// Combiner under which LB policy actions take place.
grpc_combiner* combiner_; grpc_combiner* combiner_;
/// Owned pointer to interested parties in load balancing decisions. /// Owned pointer to interested parties in load balancing decisions.

@ -575,13 +575,12 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) {
result = child_picker_->Pick(args); result = child_picker_->Pick(args);
// If pick succeeded, add LB token to initial metadata. // If pick succeeded, add LB token to initial metadata.
if (result.type == PickResult::PICK_COMPLETE && if (result.type == PickResult::PICK_COMPLETE &&
result.connected_subchannel != nullptr) { result.subchannel != nullptr) {
const grpc_arg* arg = grpc_channel_args_find( const grpc_arg* arg = grpc_channel_args_find(
result.connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); result.subchannel->channel_args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
if (arg == nullptr) { if (arg == nullptr) {
gpr_log(GPR_ERROR, gpr_log(GPR_ERROR, "[grpclb %p picker %p] No LB token for subchannel %p",
"[grpclb %p picker %p] No LB token for connected subchannel %p", parent_, this, result.subchannel.get());
parent_, this, result.connected_subchannel.get());
abort(); abort();
} }
grpc_mdelem lb_token = {reinterpret_cast<uintptr_t>(arg->value.pointer.p)}; grpc_mdelem lb_token = {reinterpret_cast<uintptr_t>(arg->value.pointer.p)};

@ -28,7 +28,6 @@
#include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/sync.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/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/connectivity_state.h"
@ -85,9 +84,8 @@ class PickFirst : public LoadBalancingPolicy {
public: public:
PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer,
const ServerAddressList& addresses, const ServerAddressList& addresses,
grpc_combiner* combiner,
const grpc_channel_args& args) const grpc_channel_args& args)
: SubchannelList(policy, tracer, addresses, combiner, : SubchannelList(policy, tracer, addresses,
policy->channel_control_helper(), args) { policy->channel_control_helper(), args) {
// Need to maintain a ref to the LB policy as long as we maintain // Need to maintain a ref to the LB policy as long as we maintain
// any references to subchannels, since the subchannels' // any references to subchannels, since the subchannels'
@ -111,19 +109,18 @@ class PickFirst : public LoadBalancingPolicy {
class Picker : public SubchannelPicker { class Picker : public SubchannelPicker {
public: public:
explicit Picker( explicit Picker(RefCountedPtr<SubchannelInterface> subchannel)
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel) : subchannel_(std::move(subchannel)) {}
: connected_subchannel_(std::move(connected_subchannel)) {}
PickResult Pick(PickArgs args) override { PickResult Pick(PickArgs args) override {
PickResult result; PickResult result;
result.type = PickResult::PICK_COMPLETE; result.type = PickResult::PICK_COMPLETE;
result.connected_subchannel = connected_subchannel_; result.subchannel = subchannel_;
return result; return result;
} }
private: private:
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel_; RefCountedPtr<SubchannelInterface> subchannel_;
}; };
void ShutdownLocked() override; void ShutdownLocked() override;
@ -166,6 +163,9 @@ void PickFirst::ShutdownLocked() {
void PickFirst::ExitIdleLocked() { void PickFirst::ExitIdleLocked() {
if (shutdown_) return; if (shutdown_) return;
if (idle_) { if (idle_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO, "Pick First %p exiting idle", this);
}
idle_ = false; idle_ = false;
if (subchannel_list_ == nullptr || if (subchannel_list_ == nullptr ||
subchannel_list_->num_subchannels() == 0) { subchannel_list_->num_subchannels() == 0) {
@ -200,7 +200,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
grpc_channel_args* new_args = grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(args.args, &new_arg, 1); grpc_channel_args_copy_and_add(args.args, &new_arg, 1);
auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>( auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); this, &grpc_lb_pick_first_trace, args.addresses, *new_args);
grpc_channel_args_destroy(new_args); grpc_channel_args_destroy(new_args);
if (subchannel_list->num_subchannels() == 0) { if (subchannel_list->num_subchannels() == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current // Empty update or no valid subchannels. Unsubscribe from all current
@ -329,7 +329,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
} else { } else {
p->channel_control_helper()->UpdateState( p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref()))); UniquePtr<SubchannelPicker>(
New<QueuePicker>(p->Ref(DEBUG_LOCATION, "QueuePicker"))));
} }
} else { } else {
if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
@ -342,20 +343,20 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->selected_ = nullptr; p->selected_ = nullptr;
CancelConnectivityWatchLocked("selected subchannel failed; going IDLE"); CancelConnectivityWatchLocked("selected subchannel failed; going IDLE");
p->channel_control_helper()->UpdateState( p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, GRPC_CHANNEL_IDLE, UniquePtr<SubchannelPicker>(New<QueuePicker>(
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref()))); p->Ref(DEBUG_LOCATION, "QueuePicker"))));
} else { } else {
// This is unlikely but can happen when a subchannel has been asked // This is unlikely but can happen when a subchannel has been asked
// to reconnect by a different channel and this channel has dropped // to reconnect by a different channel and this channel has dropped
// some connectivity state notifications. // some connectivity state notifications.
if (connectivity_state == GRPC_CHANNEL_READY) { if (connectivity_state == GRPC_CHANNEL_READY) {
p->channel_control_helper()->UpdateState( p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>( GRPC_CHANNEL_READY,
connected_subchannel()->Ref()))); UniquePtr<SubchannelPicker>(New<Picker>(subchannel()->Ref())));
} else { // CONNECTING } else { // CONNECTING
p->channel_control_helper()->UpdateState( p->channel_control_helper()->UpdateState(
connectivity_state, connectivity_state, UniquePtr<SubchannelPicker>(New<QueuePicker>(
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref()))); p->Ref(DEBUG_LOCATION, "QueuePicker"))));
} }
} }
} }
@ -411,7 +412,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
if (subchannel_list() == p->subchannel_list_.get()) { if (subchannel_list() == p->subchannel_list_.get()) {
p->channel_control_helper()->UpdateState( p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref()))); UniquePtr<SubchannelPicker>(
New<QueuePicker>(p->Ref(DEBUG_LOCATION, "QueuePicker"))));
} }
break; break;
} }
@ -445,13 +447,13 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
} }
// Cases 1 and 2. // Cases 1 and 2.
p->selected_ = this;
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY,
UniquePtr<SubchannelPicker>(New<Picker>(connected_subchannel()->Ref())));
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel());
} }
p->selected_ = this;
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY,
UniquePtr<SubchannelPicker>(New<Picker>(subchannel()->Ref())));
} }
void PickFirst::PickFirstSubchannelData:: void PickFirst::PickFirstSubchannelData::

@ -38,7 +38,6 @@
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.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/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/static_metadata.h"
@ -106,9 +105,8 @@ class RoundRobin : public LoadBalancingPolicy {
public: public:
RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer,
const ServerAddressList& addresses, const ServerAddressList& addresses,
grpc_combiner* combiner,
const grpc_channel_args& args) const grpc_channel_args& args)
: SubchannelList(policy, tracer, addresses, combiner, : SubchannelList(policy, tracer, addresses,
policy->channel_control_helper(), args) { policy->channel_control_helper(), args) {
// Need to maintain a ref to the LB policy as long as we maintain // Need to maintain a ref to the LB policy as long as we maintain
// any references to subchannels, since the subchannels' // any references to subchannels, since the subchannels'
@ -155,7 +153,7 @@ class RoundRobin : public LoadBalancingPolicy {
RoundRobin* parent_; RoundRobin* parent_;
size_t last_picked_index_; size_t last_picked_index_;
InlinedVector<RefCountedPtr<ConnectedSubchannelInterface>, 10> subchannels_; InlinedVector<RefCountedPtr<SubchannelInterface>, 10> subchannels_;
}; };
void ShutdownLocked() override; void ShutdownLocked() override;
@ -180,10 +178,9 @@ RoundRobin::Picker::Picker(RoundRobin* parent,
RoundRobinSubchannelList* subchannel_list) RoundRobinSubchannelList* subchannel_list)
: parent_(parent) { : parent_(parent) {
for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
auto* connected_subchannel = RoundRobinSubchannelData* sd = subchannel_list->subchannel(i);
subchannel_list->subchannel(i)->connected_subchannel(); if (sd->connectivity_state() == GRPC_CHANNEL_READY) {
if (connected_subchannel != nullptr) { subchannels_.push_back(sd->subchannel()->Ref());
subchannels_.push_back(connected_subchannel->Ref());
} }
} }
// For discussion on why we generate a random starting index for // For discussion on why we generate a random starting index for
@ -204,14 +201,13 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs args) {
last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size();
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"[RR %p picker %p] returning index %" PRIuPTR "[RR %p picker %p] returning index %" PRIuPTR ", subchannel=%p",
", connected_subchannel=%p",
parent_, this, last_picked_index_, parent_, this, last_picked_index_,
subchannels_[last_picked_index_].get()); subchannels_[last_picked_index_].get());
} }
PickResult result; PickResult result;
result.type = PickResult::PICK_COMPLETE; result.type = PickResult::PICK_COMPLETE;
result.connected_subchannel = subchannels_[last_picked_index_]; result.subchannel = subchannels_[last_picked_index_];
return result; return result;
} }
@ -323,8 +319,8 @@ void RoundRobin::RoundRobinSubchannelList::
} else if (num_connecting_ > 0) { } else if (num_connecting_ > 0) {
/* 2) CONNECTING */ /* 2) CONNECTING */
p->channel_control_helper()->UpdateState( p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_CHANNEL_CONNECTING, UniquePtr<SubchannelPicker>(New<QueuePicker>(
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref()))); p->Ref(DEBUG_LOCATION, "QueuePicker"))));
} else if (num_transient_failure_ == num_subchannels()) { } else if (num_transient_failure_ == num_subchannels()) {
/* 3) TRANSIENT_FAILURE */ /* 3) TRANSIENT_FAILURE */
grpc_error* error = grpc_error* error =
@ -424,7 +420,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
} }
} }
latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>( latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); this, &grpc_lb_round_robin_trace, args.addresses, *args.args);
if (latest_pending_subchannel_list_->num_subchannels() == 0) { if (latest_pending_subchannel_list_->num_subchannels() == 0) {
// If the new list is empty, immediately promote the new list to the // If the new list is empty, immediately promote the new list to the
// current list and transition to TRANSIENT_FAILURE. // current list and transition to TRANSIENT_FAILURE.

@ -39,7 +39,6 @@
#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/connectivity_state.h"
@ -64,8 +63,7 @@ class MySubchannelList
}; };
*/ */
// All methods with a Locked() suffix must be called from within the // All methods will be called from within the client_channel combiner.
// client_channel combiner.
namespace grpc_core { namespace grpc_core {
@ -93,20 +91,13 @@ class SubchannelData {
// Returns a pointer to the subchannel. // Returns a pointer to the subchannel.
SubchannelInterface* subchannel() const { return subchannel_.get(); } SubchannelInterface* subchannel() const { return subchannel_.get(); }
// Returns the connected subchannel. Will be null if the subchannel
// is not connected.
ConnectedSubchannelInterface* connected_subchannel() const {
return connected_subchannel_.get();
}
// Synchronously checks the subchannel's connectivity state. // Synchronously checks the subchannel's connectivity state.
// Must not be called while there is a connectivity notification // Must not be called while there is a connectivity notification
// pending (i.e., between calling StartConnectivityWatchLocked() and // pending (i.e., between calling StartConnectivityWatchLocked() and
// calling CancelConnectivityWatchLocked()). // calling CancelConnectivityWatchLocked()).
grpc_connectivity_state CheckConnectivityStateLocked() { grpc_connectivity_state CheckConnectivityStateLocked() {
GPR_ASSERT(pending_watcher_ == nullptr); GPR_ASSERT(pending_watcher_ == nullptr);
connectivity_state_ = connectivity_state_ = subchannel_->CheckConnectivityState();
subchannel()->CheckConnectivityState(&connected_subchannel_);
return connectivity_state_; return connectivity_state_;
} }
@ -144,7 +135,8 @@ class SubchannelData {
private: private:
// Watcher for subchannel connectivity state. // Watcher for subchannel connectivity state.
class Watcher : public SubchannelInterface::ConnectivityStateWatcher { class Watcher
: public SubchannelInterface::ConnectivityStateWatcherInterface {
public: public:
Watcher( Watcher(
SubchannelData<SubchannelListType, SubchannelDataType>* subchannel_data, SubchannelData<SubchannelListType, SubchannelDataType>* subchannel_data,
@ -154,42 +146,13 @@ class SubchannelData {
~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); } ~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); }
void OnConnectivityStateChange(grpc_connectivity_state new_state, void OnConnectivityStateChange(grpc_connectivity_state new_state) override;
RefCountedPtr<ConnectedSubchannelInterface>
connected_subchannel) override;
grpc_pollset_set* interested_parties() override { grpc_pollset_set* interested_parties() override {
return subchannel_list_->policy()->interested_parties(); return subchannel_list_->policy()->interested_parties();
} }
private: private:
// A fire-and-forget class that bounces into the combiner to process
// a connectivity state update.
class Updater {
public:
Updater(
SubchannelData<SubchannelListType, SubchannelDataType>*
subchannel_data,
RefCountedPtr<SubchannelList<SubchannelListType, SubchannelDataType>>
subchannel_list,
grpc_connectivity_state state,
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel);
~Updater() {
subchannel_list_.reset(DEBUG_LOCATION, "Watcher::Updater dtor");
}
private:
static void OnUpdateLocked(void* arg, grpc_error* error);
SubchannelData<SubchannelListType, SubchannelDataType>* subchannel_data_;
RefCountedPtr<SubchannelList<SubchannelListType, SubchannelDataType>>
subchannel_list_;
const grpc_connectivity_state state_;
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel_;
grpc_closure closure_;
};
SubchannelData<SubchannelListType, SubchannelDataType>* subchannel_data_; SubchannelData<SubchannelListType, SubchannelDataType>* subchannel_data_;
RefCountedPtr<SubchannelListType> subchannel_list_; RefCountedPtr<SubchannelListType> subchannel_list_;
}; };
@ -202,10 +165,10 @@ class SubchannelData {
// The subchannel. // The subchannel.
RefCountedPtr<SubchannelInterface> subchannel_; RefCountedPtr<SubchannelInterface> subchannel_;
// Will be non-null when the subchannel's state is being watched. // Will be non-null when the subchannel's state is being watched.
SubchannelInterface::ConnectivityStateWatcher* pending_watcher_ = nullptr; SubchannelInterface::ConnectivityStateWatcherInterface* pending_watcher_ =
nullptr;
// Data updated by the watcher. // Data updated by the watcher.
grpc_connectivity_state connectivity_state_; grpc_connectivity_state connectivity_state_;
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel_;
}; };
// A list of subchannels. // A list of subchannels.
@ -232,7 +195,6 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
// the backoff code out of subchannels and into LB policies. // the backoff code out of subchannels and into LB policies.
void ResetBackoffLocked(); void ResetBackoffLocked();
// Note: Caller must ensure that this is invoked inside of the combiner.
void Orphan() override { void Orphan() override {
ShutdownLocked(); ShutdownLocked();
InternallyRefCounted<SubchannelListType>::Unref(DEBUG_LOCATION, "shutdown"); InternallyRefCounted<SubchannelListType>::Unref(DEBUG_LOCATION, "shutdown");
@ -242,7 +204,7 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
protected: protected:
SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer,
const ServerAddressList& addresses, grpc_combiner* combiner, const ServerAddressList& addresses,
LoadBalancingPolicy::ChannelControlHelper* helper, LoadBalancingPolicy::ChannelControlHelper* helper,
const grpc_channel_args& args); const grpc_channel_args& args);
@ -263,8 +225,6 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
TraceFlag* tracer_; TraceFlag* tracer_;
grpc_combiner* combiner_;
// The list of subchannels. // The list of subchannels.
SubchannelVector subchannels_; SubchannelVector subchannels_;
@ -284,59 +244,26 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
template <typename SubchannelListType, typename SubchannelDataType> template <typename SubchannelListType, typename SubchannelDataType>
void SubchannelData<SubchannelListType, SubchannelDataType>::Watcher:: void SubchannelData<SubchannelListType, SubchannelDataType>::Watcher::
OnConnectivityStateChange( OnConnectivityStateChange(grpc_connectivity_state new_state) {
grpc_connectivity_state new_state, if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) {
RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel) {
// Will delete itself.
New<Updater>(subchannel_data_,
subchannel_list_->Ref(DEBUG_LOCATION, "Watcher::Updater"),
new_state, std::move(connected_subchannel));
}
template <typename SubchannelListType, typename SubchannelDataType>
SubchannelData<SubchannelListType, SubchannelDataType>::Watcher::Updater::
Updater(
SubchannelData<SubchannelListType, SubchannelDataType>* subchannel_data,
RefCountedPtr<SubchannelList<SubchannelListType, SubchannelDataType>>
subchannel_list,
grpc_connectivity_state state,
RefCountedPtr<ConnectedSubchannelInterface> 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 <typename SubchannelListType, typename SubchannelDataType>
void SubchannelData<SubchannelListType, SubchannelDataType>::Watcher::Updater::
OnUpdateLocked(void* arg, grpc_error* error) {
Updater* self = static_cast<Updater*>(arg);
SubchannelData* sd = self->subchannel_data_;
if (GRPC_TRACE_FLAG_ENABLED(*sd->subchannel_list_->tracer())) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
" (subchannel %p): connectivity changed: state=%s, " " (subchannel %p): connectivity changed: state=%s, "
"connected_subchannel=%p, shutting_down=%d, pending_watcher=%p", "shutting_down=%d, pending_watcher=%p",
sd->subchannel_list_->tracer()->name(), subchannel_list_->tracer()->name(), subchannel_list_->policy(),
sd->subchannel_list_->policy(), sd->subchannel_list_, sd->Index(), subchannel_list_.get(), subchannel_data_->Index(),
sd->subchannel_list_->num_subchannels(), sd->subchannel_.get(), subchannel_list_->num_subchannels(),
grpc_connectivity_state_name(self->state_), subchannel_data_->subchannel_.get(),
self->connected_subchannel_.get(), grpc_connectivity_state_name(new_state),
sd->subchannel_list_->shutting_down(), sd->pending_watcher_); subchannel_list_->shutting_down(),
subchannel_data_->pending_watcher_);
} }
if (!sd->subchannel_list_->shutting_down() && if (!subchannel_list_->shutting_down() &&
sd->pending_watcher_ != nullptr) { subchannel_data_->pending_watcher_ != nullptr) {
sd->connectivity_state_ = self->state_; subchannel_data_->connectivity_state_ = new_state;
// Get or release ref to connected subchannel.
sd->connected_subchannel_ = std::move(self->connected_subchannel_);
// Call the subclass's ProcessConnectivityChangeLocked() method. // Call the subclass's ProcessConnectivityChangeLocked() method.
sd->ProcessConnectivityChangeLocked(sd->connectivity_state_); subchannel_data_->ProcessConnectivityChangeLocked(new_state);
} }
// Clean up.
Delete(self);
} }
// //
@ -371,7 +298,6 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::
subchannel_.get()); subchannel_.get());
} }
subchannel_.reset(); subchannel_.reset();
connected_subchannel_.reset();
} }
} }
@ -400,7 +326,7 @@ void SubchannelData<SubchannelListType,
New<Watcher>(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher")); New<Watcher>(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher"));
subchannel_->WatchConnectivityState( subchannel_->WatchConnectivityState(
connectivity_state_, connectivity_state_,
UniquePtr<SubchannelInterface::ConnectivityStateWatcher>( UniquePtr<SubchannelInterface::ConnectivityStateWatcherInterface>(
pending_watcher_)); pending_watcher_));
} }
@ -434,13 +360,12 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::ShutdownLocked() {
template <typename SubchannelListType, typename SubchannelDataType> template <typename SubchannelListType, typename SubchannelDataType>
SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList( SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
LoadBalancingPolicy* policy, TraceFlag* tracer, LoadBalancingPolicy* policy, TraceFlag* tracer,
const ServerAddressList& addresses, grpc_combiner* combiner, const ServerAddressList& addresses,
LoadBalancingPolicy::ChannelControlHelper* helper, LoadBalancingPolicy::ChannelControlHelper* helper,
const grpc_channel_args& args) const grpc_channel_args& args)
: InternallyRefCounted<SubchannelListType>(tracer), : InternallyRefCounted<SubchannelListType>(tracer),
policy_(policy), policy_(policy),
tracer_(tracer), tracer_(tracer) {
combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) {
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
@ -509,7 +434,6 @@ SubchannelList<SubchannelListType, SubchannelDataType>::~SubchannelList() {
gpr_log(GPR_INFO, "[%s %p] Destroying subchannel_list %p", tracer_->name(), gpr_log(GPR_INFO, "[%s %p] Destroying subchannel_list %p", tracer_->name(),
policy_, this); policy_, this);
} }
GRPC_COMBINER_UNREF(combiner_, "subchannel_list");
} }
template <typename SubchannelListType, typename SubchannelDataType> template <typename SubchannelListType, typename SubchannelDataType>

@ -333,6 +333,8 @@ class XdsLb : public LoadBalancingPolicy {
explicit FallbackHelper(RefCountedPtr<XdsLb> parent) explicit FallbackHelper(RefCountedPtr<XdsLb> parent)
: parent_(std::move(parent)) {} : parent_(std::move(parent)) {}
~FallbackHelper() { parent_.reset(DEBUG_LOCATION, "FallbackHelper"); }
RefCountedPtr<SubchannelInterface> CreateSubchannel( RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override; const grpc_channel_args& args) override;
grpc_channel* CreateChannel(const char* target, grpc_channel* CreateChannel(const char* target,
@ -377,19 +379,30 @@ class XdsLb : public LoadBalancingPolicy {
strcmp(subzone_.get(), other.subzone_.get()) == 0; strcmp(subzone_.get(), other.subzone_.get()) == 0;
} }
const char* AsHumanReadableString() {
if (human_readable_string_ == nullptr) {
char* tmp;
gpr_asprintf(&tmp, "{region=\"%s\", zone=\"%s\", subzone=\"%s\"}",
region_.get(), zone_.get(), subzone_.get());
human_readable_string_.reset(tmp);
}
return human_readable_string_.get();
}
private: private:
UniquePtr<char> region_; UniquePtr<char> region_;
UniquePtr<char> zone_; UniquePtr<char> zone_;
UniquePtr<char> subzone_; UniquePtr<char> subzone_;
UniquePtr<char> human_readable_string_;
}; };
class LocalityMap { class LocalityMap {
public: public:
class LocalityEntry : public InternallyRefCounted<LocalityEntry> { class LocalityEntry : public InternallyRefCounted<LocalityEntry> {
public: public:
LocalityEntry(RefCountedPtr<XdsLb> parent, uint32_t locality_weight) LocalityEntry(RefCountedPtr<XdsLb> parent,
: parent_(std::move(parent)), locality_weight_(locality_weight) {} RefCountedPtr<LocalityName> name, uint32_t locality_weight);
~LocalityEntry() = default; ~LocalityEntry();
void UpdateLocked(xds_grpclb_serverlist* serverlist, void UpdateLocked(xds_grpclb_serverlist* serverlist,
LoadBalancingPolicy::Config* child_policy_config, LoadBalancingPolicy::Config* child_policy_config,
@ -404,6 +417,8 @@ class XdsLb : public LoadBalancingPolicy {
explicit Helper(RefCountedPtr<LocalityEntry> entry) explicit Helper(RefCountedPtr<LocalityEntry> entry)
: entry_(std::move(entry)) {} : entry_(std::move(entry)) {}
~Helper() { entry_.reset(DEBUG_LOCATION, "Helper"); }
RefCountedPtr<SubchannelInterface> CreateSubchannel( RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override; const grpc_channel_args& args) override;
grpc_channel* CreateChannel(const char* target, grpc_channel* CreateChannel(const char* target,
@ -428,9 +443,10 @@ class XdsLb : public LoadBalancingPolicy {
grpc_channel_args* CreateChildPolicyArgsLocked( grpc_channel_args* CreateChildPolicyArgsLocked(
const grpc_channel_args* args); const grpc_channel_args* args);
RefCountedPtr<XdsLb> parent_;
RefCountedPtr<LocalityName> name_;
OrphanablePtr<LoadBalancingPolicy> child_policy_; OrphanablePtr<LoadBalancingPolicy> child_policy_;
OrphanablePtr<LoadBalancingPolicy> pending_child_policy_; OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
RefCountedPtr<XdsLb> parent_;
RefCountedPtr<PickerRef> picker_ref_; RefCountedPtr<PickerRef> picker_ref_;
grpc_connectivity_state connectivity_state_; grpc_connectivity_state connectivity_state_;
uint32_t locality_weight_; uint32_t locality_weight_;
@ -554,7 +570,7 @@ XdsLb::PickResult XdsLb::Picker::Pick(PickArgs args) {
PickResult result = PickFromLocality(key, args); PickResult result = PickFromLocality(key, args);
// If pick succeeded, add client stats. // If pick succeeded, add client stats.
if (result.type == PickResult::PICK_COMPLETE && if (result.type == PickResult::PICK_COMPLETE &&
result.connected_subchannel != nullptr && client_stats_ != nullptr) { result.subchannel != nullptr && client_stats_ != nullptr) {
// TODO(roth): Add support for client stats. // TODO(roth): Add support for client stats.
} }
return result; return result;
@ -743,7 +759,7 @@ ServerAddressList ProcessServerlist(const xds_grpclb_serverlist* serverlist) {
XdsLb::BalancerChannelState::BalancerChannelState( XdsLb::BalancerChannelState::BalancerChannelState(
const char* balancer_name, const grpc_channel_args& args, const char* balancer_name, const grpc_channel_args& args,
grpc_core::RefCountedPtr<grpc_core::XdsLb> parent_xdslb_policy) RefCountedPtr<XdsLb> parent_xdslb_policy)
: InternallyRefCounted<BalancerChannelState>(&grpc_lb_xds_trace), : InternallyRefCounted<BalancerChannelState>(&grpc_lb_xds_trace),
xdslb_policy_(std::move(parent_xdslb_policy)), xdslb_policy_(std::move(parent_xdslb_policy)),
lb_call_backoff_( lb_call_backoff_(
@ -763,6 +779,7 @@ XdsLb::BalancerChannelState::BalancerChannelState(
} }
XdsLb::BalancerChannelState::~BalancerChannelState() { XdsLb::BalancerChannelState::~BalancerChannelState() {
xdslb_policy_.reset(DEBUG_LOCATION, "BalancerChannelState");
grpc_channel_destroy(channel_); grpc_channel_destroy(channel_);
} }
@ -1414,12 +1431,18 @@ XdsLb::XdsLb(Args args)
} }
XdsLb::~XdsLb() { XdsLb::~XdsLb() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO, "[xdslb %p] destroying xds LB policy", this);
}
gpr_free((void*)server_name_); gpr_free((void*)server_name_);
grpc_channel_args_destroy(args_); grpc_channel_args_destroy(args_);
locality_serverlist_.clear(); locality_serverlist_.clear();
} }
void XdsLb::ShutdownLocked() { void XdsLb::ShutdownLocked() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO, "[xdslb %p] shutting down", this);
}
shutting_down_ = true; shutting_down_ = true;
if (fallback_at_startup_checks_pending_) { if (fallback_at_startup_checks_pending_) {
grpc_timer_cancel(&lb_fallback_timer_); grpc_timer_cancel(&lb_fallback_timer_);
@ -1486,8 +1509,9 @@ void XdsLb::ProcessAddressesAndChannelArgsLocked(
} }
if (create_lb_channel) { if (create_lb_channel) {
OrphanablePtr<BalancerChannelState> lb_chand = OrphanablePtr<BalancerChannelState> lb_chand =
MakeOrphanable<BalancerChannelState>(balancer_name_.get(), MakeOrphanable<BalancerChannelState>(
*lb_channel_args, Ref()); balancer_name_.get(), *lb_channel_args,
Ref(DEBUG_LOCATION, "BalancerChannelState"));
if (lb_chand_ == nullptr || !lb_chand_->HasActiveCall()) { if (lb_chand_ == nullptr || !lb_chand_->HasActiveCall()) {
GPR_ASSERT(pending_lb_chand_ == nullptr); GPR_ASSERT(pending_lb_chand_ == nullptr);
// If we do not have a working LB channel yet, use the newly created one. // If we do not have a working LB channel yet, use the newly created one.
@ -1676,7 +1700,8 @@ void XdsLb::UpdateFallbackPolicyLocked() {
OrphanablePtr<LoadBalancingPolicy> XdsLb::CreateFallbackPolicyLocked( OrphanablePtr<LoadBalancingPolicy> XdsLb::CreateFallbackPolicyLocked(
const char* name, const grpc_channel_args* args) { const char* name, const grpc_channel_args* args) {
FallbackHelper* helper = New<FallbackHelper>(Ref()); FallbackHelper* helper =
New<FallbackHelper>(Ref(DEBUG_LOCATION, "FallbackHelper"));
LoadBalancingPolicy::Args lb_policy_args; LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = combiner(); lb_policy_args.combiner = combiner();
lb_policy_args.args = args; lb_policy_args.args = args;
@ -1739,7 +1764,9 @@ void XdsLb::LocalityMap::UpdateLocked(
auto iter = map_.find(locality_serverlist[i]->locality_name); auto iter = map_.find(locality_serverlist[i]->locality_name);
if (iter == map_.end()) { if (iter == map_.end()) {
OrphanablePtr<LocalityEntry> new_entry = MakeOrphanable<LocalityEntry>( OrphanablePtr<LocalityEntry> new_entry = MakeOrphanable<LocalityEntry>(
parent->Ref(), locality_serverlist[i]->locality_weight); parent->Ref(DEBUG_LOCATION, "LocalityEntry"),
locality_serverlist[i]->locality_name,
locality_serverlist[i]->locality_weight);
iter = map_.emplace(locality_serverlist[i]->locality_name, iter = map_.emplace(locality_serverlist[i]->locality_name,
std::move(new_entry)) std::move(new_entry))
.first; .first;
@ -1764,6 +1791,27 @@ void XdsLb::LocalityMap::ResetBackoffLocked() {
// XdsLb::LocalityMap::LocalityEntry // XdsLb::LocalityMap::LocalityEntry
// //
XdsLb::LocalityMap::LocalityEntry::LocalityEntry(
RefCountedPtr<XdsLb> parent, RefCountedPtr<LocalityName> name,
uint32_t locality_weight)
: parent_(std::move(parent)),
name_(std::move(name)),
locality_weight_(locality_weight) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO, "[xdslb %p] created LocalityEntry %p for %s",
parent_.get(), this, name_->AsHumanReadableString());
}
}
XdsLb::LocalityMap::LocalityEntry::~LocalityEntry() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO,
"[xdslb %p] LocalityEntry %p %s: destroying locality entry",
parent_.get(), this, name_->AsHumanReadableString());
}
parent_.reset(DEBUG_LOCATION, "LocalityEntry");
}
grpc_channel_args* grpc_channel_args*
XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked( XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked(
const grpc_channel_args* args_in) { const grpc_channel_args* args_in) {
@ -1785,7 +1833,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked(
OrphanablePtr<LoadBalancingPolicy> OrphanablePtr<LoadBalancingPolicy>
XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked(
const char* name, const grpc_channel_args* args) { const char* name, const grpc_channel_args* args) {
Helper* helper = New<Helper>(this->Ref()); Helper* helper = New<Helper>(this->Ref(DEBUG_LOCATION, "Helper"));
LoadBalancingPolicy::Args lb_policy_args; LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = parent_->combiner(); lb_policy_args.combiner = parent_->combiner();
lb_policy_args.args = args; lb_policy_args.args = args;
@ -1795,13 +1843,16 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked(
LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
name, std::move(lb_policy_args)); name, std::move(lb_policy_args));
if (GPR_UNLIKELY(lb_policy == nullptr)) { if (GPR_UNLIKELY(lb_policy == nullptr)) {
gpr_log(GPR_ERROR, "[xdslb %p] Failure creating child policy %s", this, gpr_log(GPR_ERROR,
name); "[xdslb %p] LocalityEntry %p %s: failure creating child policy %s",
parent_.get(), this, name_->AsHumanReadableString(), name);
return nullptr; return nullptr;
} }
helper->set_child(lb_policy.get()); helper->set_child(lb_policy.get());
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO, "[xdslb %p] Created new child policy %s (%p)", this, name, gpr_log(GPR_INFO,
"[xdslb %p] LocalityEntry %p %s: Created new child policy %s (%p)",
parent_.get(), this, name_->AsHumanReadableString(), name,
lb_policy.get()); lb_policy.get());
} }
// Add the xDS's interested_parties pollset_set to that of the newly created // Add the xDS's interested_parties pollset_set to that of the newly created
@ -1892,7 +1943,9 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
// If child_policy_ is null, we set it (case 1), else we set // If child_policy_ is null, we set it (case 1), else we set
// pending_child_policy_ (cases 2b and 3b). // pending_child_policy_ (cases 2b and 3b).
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this, gpr_log(GPR_INFO,
"[xdslb %p] LocalityEntry %p %s: Creating new %schild policy %s",
parent_.get(), this, name_->AsHumanReadableString(),
child_policy_ == nullptr ? "" : "pending ", child_policy_name); child_policy_ == nullptr ? "" : "pending ", child_policy_name);
} }
auto& lb_policy = auto& lb_policy =
@ -1910,7 +1963,9 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
GPR_ASSERT(policy_to_update != nullptr); GPR_ASSERT(policy_to_update != nullptr);
// Update the policy. // Update the policy.
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO, "[xdslb %p] Updating %schild policy %p", this, gpr_log(GPR_INFO,
"[xdslb %p] LocalityEntry %p %s: Updating %schild policy %p",
parent_.get(), this, name_->AsHumanReadableString(),
policy_to_update == pending_child_policy_.get() ? "pending " : "", policy_to_update == pending_child_policy_.get() ? "pending " : "",
policy_to_update); policy_to_update);
} }
@ -1918,17 +1973,25 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
} }
void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() { void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
gpr_log(GPR_INFO,
"[xdslb %p] LocalityEntry %p %s: shutting down locality entry",
parent_.get(), this, name_->AsHumanReadableString());
}
// Remove the child policy's interested_parties pollset_set from the // Remove the child policy's interested_parties pollset_set from the
// xDS policy. // xDS policy.
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
parent_->interested_parties()); parent_->interested_parties());
child_policy_.reset();
if (pending_child_policy_ != nullptr) { if (pending_child_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set( grpc_pollset_set_del_pollset_set(
pending_child_policy_->interested_parties(), pending_child_policy_->interested_parties(),
parent_->interested_parties()); parent_->interested_parties());
pending_child_policy_.reset();
} }
child_policy_.reset(); // Drop our ref to the child's picker, in case it's holding a ref to
pending_child_policy_.reset(); // the child.
picker_ref_.reset();
} }
void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() {
@ -2061,11 +2124,13 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
} else if (num_connecting > 0) { } else if (num_connecting > 0) {
entry_->parent_->channel_control_helper()->UpdateState( entry_->parent_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(this->entry_->parent_))); UniquePtr<SubchannelPicker>(New<QueuePicker>(
this->entry_->parent_->Ref(DEBUG_LOCATION, "QueuePicker"))));
} else if (num_idle > 0) { } else if (num_idle > 0) {
entry_->parent_->channel_control_helper()->UpdateState( entry_->parent_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, GRPC_CHANNEL_IDLE,
UniquePtr<SubchannelPicker>(New<QueuePicker>(this->entry_->parent_))); UniquePtr<SubchannelPicker>(New<QueuePicker>(
this->entry_->parent_->Ref(DEBUG_LOCATION, "QueuePicker"))));
} else { } else {
GPR_ASSERT(num_transient_failures == locality_map.size()); GPR_ASSERT(num_transient_failures == locality_map.size());
grpc_error* error = grpc_error* error =

@ -117,12 +117,10 @@ class Resolver : public InternallyRefCounted<Resolver> {
/// implementations. At that point, this method can go away. /// implementations. At that point, this method can go away.
virtual void ResetBackoffLocked() {} virtual void ResetBackoffLocked() {}
// Note: This must be invoked while holding the combiner.
void Orphan() override { void Orphan() override {
// Invoke ShutdownAndUnrefLocked() inside of the combiner. ShutdownLocked();
GRPC_CLOSURE_SCHED( Unref();
GRPC_CLOSURE_CREATE(&Resolver::ShutdownAndUnrefLocked, this,
grpc_combiner_scheduler(combiner_)),
GRPC_ERROR_NONE);
} }
GRPC_ABSTRACT_BASE_CLASS GRPC_ABSTRACT_BASE_CLASS
@ -147,12 +145,6 @@ class Resolver : public InternallyRefCounted<Resolver> {
ResultHandler* result_handler() const { return result_handler_.get(); } ResultHandler* result_handler() const { return result_handler_.get(); }
private: private:
static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) {
Resolver* resolver = static_cast<Resolver*>(arg);
resolver->ShutdownLocked();
resolver->Unref();
}
UniquePtr<ResultHandler> result_handler_; UniquePtr<ResultHandler> result_handler_;
grpc_combiner* combiner_; grpc_combiner* combiner_;
}; };

@ -86,7 +86,7 @@ ConnectedSubchannel::ConnectedSubchannel(
grpc_channel_stack* channel_stack, const grpc_channel_args* args, grpc_channel_stack* channel_stack, const grpc_channel_args* args,
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel, RefCountedPtr<channelz::SubchannelNode> channelz_subchannel,
intptr_t socket_uuid) intptr_t socket_uuid)
: ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount), : RefCounted<ConnectedSubchannel>(&grpc_trace_subchannel_refcount),
channel_stack_(channel_stack), channel_stack_(channel_stack),
args_(grpc_channel_args_copy(args)), args_(grpc_channel_args_copy(args)),
channelz_subchannel_(std::move(channelz_subchannel)), channelz_subchannel_(std::move(channelz_subchannel)),
@ -378,12 +378,12 @@ class Subchannel::ConnectedSubchannelStateWatcher {
// //
void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked( void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked(
UniquePtr<ConnectivityStateWatcher> watcher) { OrphanablePtr<ConnectivityStateWatcherInterface> watcher) {
watchers_.insert(MakePair(watcher.get(), std::move(watcher))); watchers_.insert(MakePair(watcher.get(), std::move(watcher)));
} }
void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked(
ConnectivityStateWatcher* watcher) { ConnectivityStateWatcherInterface* watcher) {
watchers_.erase(watcher); watchers_.erase(watcher);
} }
@ -438,8 +438,9 @@ class Subchannel::HealthWatcherMap::HealthWatcher
grpc_connectivity_state state() const { return state_; } grpc_connectivity_state state() const { return state_; }
void AddWatcherLocked(grpc_connectivity_state initial_state, void AddWatcherLocked(
UniquePtr<ConnectivityStateWatcher> watcher) { grpc_connectivity_state initial_state,
OrphanablePtr<ConnectivityStateWatcherInterface> watcher) {
if (state_ != initial_state) { if (state_ != initial_state) {
RefCountedPtr<ConnectedSubchannel> connected_subchannel; RefCountedPtr<ConnectedSubchannel> connected_subchannel;
if (state_ == GRPC_CHANNEL_READY) { if (state_ == GRPC_CHANNEL_READY) {
@ -451,7 +452,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher
watcher_list_.AddWatcherLocked(std::move(watcher)); watcher_list_.AddWatcherLocked(std::move(watcher));
} }
void RemoveWatcherLocked(ConnectivityStateWatcher* watcher) { void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher) {
watcher_list_.RemoveWatcherLocked(watcher); watcher_list_.RemoveWatcherLocked(watcher);
} }
@ -527,7 +528,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher
void Subchannel::HealthWatcherMap::AddWatcherLocked( void Subchannel::HealthWatcherMap::AddWatcherLocked(
Subchannel* subchannel, grpc_connectivity_state initial_state, Subchannel* subchannel, grpc_connectivity_state initial_state,
UniquePtr<char> health_check_service_name, UniquePtr<char> health_check_service_name,
UniquePtr<ConnectivityStateWatcher> watcher) { OrphanablePtr<ConnectivityStateWatcherInterface> watcher) {
// If the health check service name is not already present in the map, // If the health check service name is not already present in the map,
// add it. // add it.
auto it = map_.find(health_check_service_name.get()); auto it = map_.find(health_check_service_name.get());
@ -546,7 +547,8 @@ void Subchannel::HealthWatcherMap::AddWatcherLocked(
} }
void Subchannel::HealthWatcherMap::RemoveWatcherLocked( void Subchannel::HealthWatcherMap::RemoveWatcherLocked(
const char* health_check_service_name, ConnectivityStateWatcher* watcher) { const char* health_check_service_name,
ConnectivityStateWatcherInterface* watcher) {
auto it = map_.find(health_check_service_name); auto it = map_.find(health_check_service_name);
GPR_ASSERT(it != map_.end()); GPR_ASSERT(it != map_.end());
it->second->RemoveWatcherLocked(watcher); it->second->RemoveWatcherLocked(watcher);
@ -818,7 +820,7 @@ grpc_connectivity_state Subchannel::CheckConnectivityState(
void Subchannel::WatchConnectivityState( void Subchannel::WatchConnectivityState(
grpc_connectivity_state initial_state, grpc_connectivity_state initial_state,
UniquePtr<char> health_check_service_name, UniquePtr<char> health_check_service_name,
UniquePtr<ConnectivityStateWatcher> watcher) { OrphanablePtr<ConnectivityStateWatcherInterface> watcher) {
MutexLock lock(&mu_); MutexLock lock(&mu_);
grpc_pollset_set* interested_parties = watcher->interested_parties(); grpc_pollset_set* interested_parties = watcher->interested_parties();
if (interested_parties != nullptr) { if (interested_parties != nullptr) {
@ -837,7 +839,8 @@ void Subchannel::WatchConnectivityState(
} }
void Subchannel::CancelConnectivityStateWatch( void Subchannel::CancelConnectivityStateWatch(
const char* health_check_service_name, ConnectivityStateWatcher* watcher) { const char* health_check_service_name,
ConnectivityStateWatcherInterface* watcher) {
MutexLock lock(&mu_); MutexLock lock(&mu_);
grpc_pollset_set* interested_parties = watcher->interested_parties(); grpc_pollset_set* interested_parties = watcher->interested_parties();
if (interested_parties != nullptr) { if (interested_parties != nullptr) {

@ -23,7 +23,6 @@
#include "src/core/ext/filters/client_channel/client_channel_channelz.h" #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/connector.h"
#include "src/core/ext/filters/client_channel/subchannel_interface.h"
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
#include "src/core/lib/backoff/backoff.h" #include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack.h"
@ -70,7 +69,7 @@ namespace grpc_core {
class SubchannelCall; class SubchannelCall;
class ConnectedSubchannel : public ConnectedSubchannelInterface { class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
public: public:
struct CallArgs { struct CallArgs {
grpc_polling_entity* pollent; grpc_polling_entity* pollent;
@ -97,7 +96,7 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface {
grpc_error** error); grpc_error** error);
grpc_channel_stack* channel_stack() const { return channel_stack_; } grpc_channel_stack* channel_stack() const { return channel_stack_; }
const grpc_channel_args* args() const override { return args_; } const grpc_channel_args* args() const { return args_; }
channelz::SubchannelNode* channelz_subchannel() const { channelz::SubchannelNode* channelz_subchannel() const {
return channelz_subchannel_.get(); return channelz_subchannel_.get();
} }
@ -176,10 +175,35 @@ class SubchannelCall {
// A subchannel that knows how to connect to exactly one target address. It // A subchannel that knows how to connect to exactly one target address. It
// provides a target for load balancing. // provides a target for load balancing.
//
// Note that this is the "real" subchannel implementation, whose API is
// different from the SubchannelInterface that is exposed to LB policy
// implementations. The client channel provides an adaptor class
// (SubchannelWrapper) that "converts" between the two.
class Subchannel { class Subchannel {
public: public:
typedef SubchannelInterface::ConnectivityStateWatcher class ConnectivityStateWatcherInterface
ConnectivityStateWatcher; : public InternallyRefCounted<ConnectivityStateWatcherInterface> {
public:
virtual ~ConnectivityStateWatcherInterface() = default;
// 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<ConnectedSubchannel> connected_subchannel) // NOLINT
GRPC_ABSTRACT;
virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT;
GRPC_ABSTRACT_BASE_CLASS
};
// The ctor and dtor are not intended to use directly. // The ctor and dtor are not intended to use directly.
Subchannel(SubchannelKey* key, grpc_connector* connector, Subchannel(SubchannelKey* key, grpc_connector* connector,
@ -206,6 +230,8 @@ class Subchannel {
// Caller doesn't take ownership. // Caller doesn't take ownership.
const char* GetTargetAddress(); const char* GetTargetAddress();
const grpc_channel_args* channel_args() const { return args_; }
channelz::SubchannelNode* channelz_node(); channelz::SubchannelNode* channelz_node();
// Returns the current connectivity state of the subchannel. // Returns the current connectivity state of the subchannel.
@ -225,14 +251,15 @@ class Subchannel {
// changes. // changes.
// The watcher will be destroyed either when the subchannel is // The watcher will be destroyed either when the subchannel is
// destroyed or when CancelConnectivityStateWatch() is called. // destroyed or when CancelConnectivityStateWatch() is called.
void WatchConnectivityState(grpc_connectivity_state initial_state, void WatchConnectivityState(
UniquePtr<char> health_check_service_name, grpc_connectivity_state initial_state,
UniquePtr<ConnectivityStateWatcher> watcher); UniquePtr<char> health_check_service_name,
OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
// Cancels a connectivity state watch. // Cancels a connectivity state watch.
// If the watcher has already been destroyed, this is a no-op. // If the watcher has already been destroyed, this is a no-op.
void CancelConnectivityStateWatch(const char* health_check_service_name, void CancelConnectivityStateWatch(const char* health_check_service_name,
ConnectivityStateWatcher* watcher); ConnectivityStateWatcherInterface* watcher);
// Attempt to connect to the backend. Has no effect if already connected. // Attempt to connect to the backend. Has no effect if already connected.
void AttemptToConnect(); void AttemptToConnect();
@ -257,14 +284,15 @@ class Subchannel {
grpc_resolved_address* addr); grpc_resolved_address* addr);
private: private:
// A linked list of ConnectivityStateWatchers that are monitoring the // A linked list of ConnectivityStateWatcherInterfaces that are monitoring
// subchannel's state. // the subchannel's state.
class ConnectivityStateWatcherList { class ConnectivityStateWatcherList {
public: public:
~ConnectivityStateWatcherList() { Clear(); } ~ConnectivityStateWatcherList() { Clear(); }
void AddWatcherLocked(UniquePtr<ConnectivityStateWatcher> watcher); void AddWatcherLocked(
void RemoveWatcherLocked(ConnectivityStateWatcher* watcher); OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher);
// Notifies all watchers in the list about a change to state. // Notifies all watchers in the list about a change to state.
void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state);
@ -276,12 +304,13 @@ class Subchannel {
private: private:
// TODO(roth): This could be a set instead of a map if we had a set // TODO(roth): This could be a set instead of a map if we had a set
// implementation. // implementation.
Map<ConnectivityStateWatcher*, UniquePtr<ConnectivityStateWatcher>> Map<ConnectivityStateWatcherInterface*,
OrphanablePtr<ConnectivityStateWatcherInterface>>
watchers_; watchers_;
}; };
// A map that tracks ConnectivityStateWatchers using a particular health // A map that tracks ConnectivityStateWatcherInterfaces using a particular
// check service name. // health check service name.
// //
// There is one entry in the map for each 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 // Entries exist only as long as there are watchers using the
@ -291,12 +320,12 @@ class Subchannel {
// state READY. // state READY.
class HealthWatcherMap { class HealthWatcherMap {
public: public:
void AddWatcherLocked(Subchannel* subchannel, void AddWatcherLocked(
grpc_connectivity_state initial_state, Subchannel* subchannel, grpc_connectivity_state initial_state,
UniquePtr<char> health_check_service_name, UniquePtr<char> health_check_service_name,
UniquePtr<ConnectivityStateWatcher> watcher); OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
void RemoveWatcherLocked(const char* health_check_service_name, void RemoveWatcherLocked(const char* health_check_service_name,
ConnectivityStateWatcher* watcher); ConnectivityStateWatcherInterface* watcher);
// Notifies the watcher when the subchannel's state changes. // Notifies the watcher when the subchannel's state changes.
void NotifyLocked(grpc_connectivity_state state); void NotifyLocked(grpc_connectivity_state state);

@ -21,42 +21,22 @@
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/ref_counted_ptr.h"
namespace grpc_core { namespace grpc_core {
// TODO(roth): In a subsequent PR, remove this from this API. // The interface for subchannels that is exposed to LB policy implementations.
class ConnectedSubchannelInterface
: public RefCounted<ConnectedSubchannelInterface> {
public:
virtual const grpc_channel_args* args() const GRPC_ABSTRACT;
protected:
template <typename TraceFlagT = TraceFlag>
explicit ConnectedSubchannelInterface(TraceFlagT* trace_flag = nullptr)
: RefCounted<ConnectedSubchannelInterface>(trace_flag) {}
};
class SubchannelInterface : public RefCounted<SubchannelInterface> { class SubchannelInterface : public RefCounted<SubchannelInterface> {
public: public:
class ConnectivityStateWatcher { class ConnectivityStateWatcherInterface {
public: public:
virtual ~ConnectivityStateWatcher() = default; virtual ~ConnectivityStateWatcherInterface() = default;
// Will be invoked whenever the subchannel's connectivity state // Will be invoked whenever the subchannel's connectivity state
// changes. There will be only one invocation of this method on a // changes. There will be only one invocation of this method on a
// given watcher instance at any given time. // given watcher instance at any given time.
// virtual void OnConnectivityStateChange(grpc_connectivity_state new_state)
// 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<ConnectedSubchannelInterface>
connected_subchannel) // NOLINT
GRPC_ABSTRACT; GRPC_ABSTRACT;
// TODO(roth): Remove this as soon as we move to EventManager-based // TODO(roth): Remove this as soon as we move to EventManager-based
@ -66,12 +46,14 @@ class SubchannelInterface : public RefCounted<SubchannelInterface> {
GRPC_ABSTRACT_BASE_CLASS GRPC_ABSTRACT_BASE_CLASS
}; };
template <typename TraceFlagT = TraceFlag>
explicit SubchannelInterface(TraceFlagT* trace_flag = nullptr)
: RefCounted<SubchannelInterface>(trace_flag) {}
virtual ~SubchannelInterface() = default; virtual ~SubchannelInterface() = default;
// Returns the current connectivity state of the subchannel. // Returns the current connectivity state of the subchannel.
virtual grpc_connectivity_state CheckConnectivityState( virtual grpc_connectivity_state CheckConnectivityState() GRPC_ABSTRACT;
RefCountedPtr<ConnectedSubchannelInterface>* connected_subchannel)
GRPC_ABSTRACT;
// Starts watching the subchannel's connectivity state. // Starts watching the subchannel's connectivity state.
// The first callback to the watcher will be delivered when the // The first callback to the watcher will be delivered when the
@ -86,12 +68,12 @@ class SubchannelInterface : public RefCounted<SubchannelInterface> {
// the previous watcher using CancelConnectivityStateWatch(). // the previous watcher using CancelConnectivityStateWatch().
virtual void WatchConnectivityState( virtual void WatchConnectivityState(
grpc_connectivity_state initial_state, grpc_connectivity_state initial_state,
UniquePtr<ConnectivityStateWatcher> watcher) GRPC_ABSTRACT; UniquePtr<ConnectivityStateWatcherInterface> watcher) GRPC_ABSTRACT;
// Cancels a connectivity state watch. // Cancels a connectivity state watch.
// If the watcher has already been destroyed, this is a no-op. // If the watcher has already been destroyed, this is a no-op.
virtual void CancelConnectivityStateWatch(ConnectivityStateWatcher* watcher) virtual void CancelConnectivityStateWatch(
GRPC_ABSTRACT; ConnectivityStateWatcherInterface* watcher) GRPC_ABSTRACT;
// Attempt to connect to the backend. Has no effect if already connected. // Attempt to connect to the backend. Has no effect if already connected.
// If the subchannel is currently in backoff delay due to a previously // If the subchannel is currently in backoff delay due to a previously
@ -105,6 +87,9 @@ class SubchannelInterface : public RefCounted<SubchannelInterface> {
// attempt will be started as soon as AttemptToConnect() is called. // attempt will be started as soon as AttemptToConnect() is called.
virtual void ResetBackoff() GRPC_ABSTRACT; virtual void ResetBackoff() GRPC_ABSTRACT;
// TODO(roth): Need a better non-grpc-specific abstraction here.
virtual const grpc_channel_args* channel_args() GRPC_ABSTRACT;
GRPC_ABSTRACT_BASE_CLASS GRPC_ABSTRACT_BASE_CLASS
}; };

@ -30,6 +30,7 @@
#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/pair.h" #include "src/core/lib/gprpp/pair.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
namespace grpc_core { namespace grpc_core {
struct StringLess { struct StringLess {
@ -41,6 +42,13 @@ struct StringLess {
} }
}; };
template <typename T>
struct RefCountedPtrLess {
bool operator()(const RefCountedPtr<T>& p1, const RefCountedPtr<T>& p2) {
return p1.get() < p2.get();
}
};
namespace testing { namespace testing {
class MapTest; class MapTest;
} }
@ -55,8 +63,28 @@ class Map {
typedef Compare key_compare; typedef Compare key_compare;
class iterator; class iterator;
Map() {}
~Map() { clear(); } ~Map() { clear(); }
// Copying not currently supported.
Map(const Map& other) = delete;
// Move support.
Map(Map&& other) : root_(other.root_), size_(other.size_) {
other.root_ = nullptr;
other.size_ = 0;
}
Map& operator=(Map&& other) {
if (this != &other) {
clear();
root_ = other.root_;
size_ = other.size_;
other.root_ = nullptr;
other.size_ = 0;
}
return *this;
}
T& operator[](key_type&& key); T& operator[](key_type&& key);
T& operator[](const key_type& key); T& operator[](const key_type& key);
iterator find(const key_type& k); iterator find(const key_type& k);

@ -28,7 +28,7 @@
namespace grpc_core { namespace grpc_core {
TraceFlag grpc_call_combiner_trace(false, "call_combiner"); DebugOnlyTraceFlag grpc_call_combiner_trace(false, "call_combiner");
namespace { namespace {

@ -43,7 +43,7 @@
namespace grpc_core { namespace grpc_core {
extern TraceFlag grpc_call_combiner_trace; extern DebugOnlyTraceFlag grpc_call_combiner_trace;
class CallCombiner { class CallCombiner {
public: public:

@ -18,6 +18,7 @@
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/port.h" #include "src/core/lib/iomgr/port.h"
#ifdef GRPC_CFSTREAM #ifdef GRPC_CFSTREAM
@ -47,7 +48,7 @@ void CFStreamHandle::Release(void* info) {
CFStreamHandle* CFStreamHandle::CreateStreamHandle( CFStreamHandle* CFStreamHandle::CreateStreamHandle(
CFReadStreamRef read_stream, CFWriteStreamRef write_stream) { CFReadStreamRef read_stream, CFWriteStreamRef write_stream) {
return new CFStreamHandle(read_stream, write_stream); return grpc_core::New<CFStreamHandle>(read_stream, write_stream);
} }
void CFStreamHandle::ReadCallback(CFReadStreamRef stream, void CFStreamHandle::ReadCallback(CFReadStreamRef stream,
@ -188,7 +189,7 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) {
reason, val, val - 1); reason, val, val - 1);
} }
if (gpr_unref(&refcount_)) { if (gpr_unref(&refcount_)) {
delete this; grpc_core::Delete<CFStreamHandle>(this);
} }
} }

@ -29,6 +29,7 @@
#ifdef GRPC_CFSTREAM #ifdef GRPC_CFSTREAM
#import <CoreFoundation/CoreFoundation.h> #import <CoreFoundation/CoreFoundation.h>
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/lockfree_event.h" #include "src/core/lib/iomgr/lockfree_event.h"
@ -65,6 +66,9 @@ class CFStreamHandle final {
dispatch_queue_t dispatch_queue_; dispatch_queue_t dispatch_queue_;
gpr_refcount refcount_; gpr_refcount refcount_;
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
}; };
#ifdef DEBUG #ifdef DEBUG

@ -44,11 +44,11 @@ GPR_GLOBAL_CONFIG_DEFINE_STRING(
"This is a comma-separated list of engines, which are tried in priority " "This is a comma-separated list of engines, which are tried in priority "
"order first -> last.") "order first -> last.")
grpc_core::TraceFlag grpc_polling_trace(false, grpc_core::DebugOnlyTraceFlag grpc_polling_trace(
"polling"); /* Disabled by default */ false, "polling"); /* Disabled by default */
/* Traces fd create/close operations */ /* Traces fd create/close operations */
grpc_core::TraceFlag grpc_fd_trace(false, "fd_trace"); grpc_core::DebugOnlyTraceFlag grpc_fd_trace(false, "fd_trace");
grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount"); grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount");
grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api");

@ -32,8 +32,9 @@
GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy); GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy);
extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */ extern grpc_core::DebugOnlyTraceFlag grpc_fd_trace; /* Disabled by default */
extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */ extern grpc_core::DebugOnlyTraceFlag
grpc_polling_trace; /* Disabled by default */
#define GRPC_FD_TRACE(format, ...) \ #define GRPC_FD_TRACE(format, ...) \
if (GRPC_TRACE_FLAG_ENABLED(grpc_fd_trace)) { \ if (GRPC_TRACE_FLAG_ENABLED(grpc_fd_trace)) { \

@ -24,7 +24,7 @@
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
grpc_core::TraceFlag grpc_polling_trace(false, grpc_core::DebugOnlyTraceFlag grpc_polling_trace(
"polling"); /* Disabled by default */ false, "polling"); /* Disabled by default */
#endif // GRPC_WINSOCK_SOCKET #endif // GRPC_WINSOCK_SOCKET

@ -24,7 +24,7 @@
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
extern grpc_core::TraceFlag grpc_polling_trace; extern grpc_core::DebugOnlyTraceFlag grpc_polling_trace;
/* 'state' holds the to call when the fd is readable or writable respectively. /* 'state' holds the to call when the fd is readable or writable respectively.
It can contain one of the following values: It can contain one of the following values:

@ -26,6 +26,11 @@
#define GRPC_CUSTOM_SOCKET #define GRPC_CUSTOM_SOCKET
#endif #endif
#endif #endif
/* This needs to be separate from the other conditions because it needs to
* apply to custom sockets too */
#ifdef GPR_WINDOWS
#define GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY 1
#endif
#if defined(GRPC_CUSTOM_SOCKET) #if defined(GRPC_CUSTOM_SOCKET)
// Do Nothing // Do Nothing
#elif defined(GPR_MANYLINUX1) #elif defined(GPR_MANYLINUX1)
@ -45,7 +50,6 @@
#define GRPC_WINSOCK_SOCKET 1 #define GRPC_WINSOCK_SOCKET 1
#define GRPC_WINDOWS_SOCKETUTILS 1 #define GRPC_WINDOWS_SOCKETUTILS 1
#define GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER 1 #define GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER 1
#define GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY 1
#elif defined(GPR_ANDROID) #elif defined(GPR_ANDROID)
#define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IPV6_RECVPKTINFO 1
#define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_IP_PKTINFO 1

@ -53,7 +53,7 @@ typedef struct uv_socket_t {
char* read_buf; char* read_buf;
size_t read_len; size_t read_len;
bool pending_connection; int pending_connections;
grpc_custom_socket* accept_socket; grpc_custom_socket* accept_socket;
grpc_error* accept_error; grpc_error* accept_error;
@ -206,7 +206,7 @@ static grpc_error* uv_socket_init_helper(uv_socket_t* uv_socket, int domain) {
// Node uses a garbage collector to call destructors, so we don't // Node uses a garbage collector to call destructors, so we don't
// want to hold the uv loop open with active gRPC objects. // want to hold the uv loop open with active gRPC objects.
uv_unref((uv_handle_t*)uv_socket->handle); uv_unref((uv_handle_t*)uv_socket->handle);
uv_socket->pending_connection = false; uv_socket->pending_connections = 0;
uv_socket->accept_socket = nullptr; uv_socket->accept_socket = nullptr;
uv_socket->accept_error = GRPC_ERROR_NONE; uv_socket->accept_error = GRPC_ERROR_NONE;
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
@ -243,14 +243,14 @@ static grpc_error* uv_socket_getsockname(grpc_custom_socket* socket,
static void accept_new_connection(grpc_custom_socket* socket) { static void accept_new_connection(grpc_custom_socket* socket) {
uv_socket_t* uv_socket = (uv_socket_t*)socket->impl; uv_socket_t* uv_socket = (uv_socket_t*)socket->impl;
if (!uv_socket->pending_connection || !uv_socket->accept_socket) { if (uv_socket->pending_connections == 0 || !uv_socket->accept_socket) {
return; return;
} }
grpc_custom_socket* new_socket = uv_socket->accept_socket; grpc_custom_socket* new_socket = uv_socket->accept_socket;
grpc_error* error = uv_socket->accept_error; grpc_error* error = uv_socket->accept_error;
uv_socket->accept_socket = nullptr; uv_socket->accept_socket = nullptr;
uv_socket->accept_error = GRPC_ERROR_NONE; uv_socket->accept_error = GRPC_ERROR_NONE;
uv_socket->pending_connection = false; uv_socket->pending_connections -= 1;
if (uv_socket->accept_error != GRPC_ERROR_NONE) { if (uv_socket->accept_error != GRPC_ERROR_NONE) {
uv_stream_t dummy_handle; uv_stream_t dummy_handle;
uv_accept((uv_stream_t*)uv_socket->handle, &dummy_handle); uv_accept((uv_stream_t*)uv_socket->handle, &dummy_handle);
@ -270,8 +270,6 @@ static void accept_new_connection(grpc_custom_socket* socket) {
static void uv_on_connect(uv_stream_t* server, int status) { static void uv_on_connect(uv_stream_t* server, int status) {
grpc_custom_socket* socket = (grpc_custom_socket*)server->data; grpc_custom_socket* socket = (grpc_custom_socket*)server->data;
uv_socket_t* uv_socket = (uv_socket_t*)socket->impl; uv_socket_t* uv_socket = (uv_socket_t*)socket->impl;
GPR_ASSERT(!uv_socket->pending_connection);
uv_socket->pending_connection = true;
if (status < 0) { if (status < 0) {
switch (status) { switch (status) {
case UV_EINTR: case UV_EINTR:
@ -281,6 +279,7 @@ static void uv_on_connect(uv_stream_t* server, int status) {
uv_socket->accept_error = tcp_error_create("accept failed", status); uv_socket->accept_error = tcp_error_create("accept failed", status);
} }
} }
uv_socket->pending_connections += 1;
accept_new_connection(socket); accept_new_connection(socket);
} }

@ -195,7 +195,7 @@ void SecurityHandshaker::HandshakeFailedLocked(grpc_error* error) {
void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) {
MutexLock lock(&mu_); MutexLock lock(&mu_);
if (error != GRPC_ERROR_NONE || is_shutdown_) { if (error != GRPC_ERROR_NONE || is_shutdown_) {
HandshakeFailedLocked(GRPC_ERROR_REF(error)); HandshakeFailedLocked(error);
return; return;
} }
// Create zero-copy frame protector, if implemented. // Create zero-copy frame protector, if implemented.
@ -255,7 +255,7 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) {
void SecurityHandshaker::OnPeerCheckedFn(void* arg, grpc_error* error) { void SecurityHandshaker::OnPeerCheckedFn(void* arg, grpc_error* error) {
RefCountedPtr<SecurityHandshaker>(static_cast<SecurityHandshaker*>(arg)) RefCountedPtr<SecurityHandshaker>(static_cast<SecurityHandshaker*>(arg))
->OnPeerCheckedInner(error); ->OnPeerCheckedInner(GRPC_ERROR_REF(error));
} }
grpc_error* SecurityHandshaker::CheckPeerLocked() { grpc_error* SecurityHandshaker::CheckPeerLocked() {

@ -32,35 +32,45 @@
/* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */ /* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */
#define GROW(x) (3 * (x) / 2) #define GROW(x) (3 * (x) / 2)
/* Typically, we do not actually need to embiggen (by calling
* memmove/malloc/realloc) - only if we were up against the full capacity of the
* slice buffer. If do_embiggen is inlined, the compiler clobbers multiple
* registers pointlessly in the common case. */
static void GPR_ATTRIBUTE_NOINLINE do_embiggen(grpc_slice_buffer* sb,
const size_t slice_count,
const size_t slice_offset) {
if (slice_offset != 0) {
/* Make room by moving elements if there's still space unused */
memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
sb->slices = sb->base_slices;
} else {
/* Allocate more memory if no more space is available */
const size_t new_capacity = GROW(sb->capacity);
sb->capacity = new_capacity;
if (sb->base_slices == sb->inlined) {
sb->base_slices = static_cast<grpc_slice*>(
gpr_malloc(new_capacity * sizeof(grpc_slice)));
memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
} else {
sb->base_slices = static_cast<grpc_slice*>(
gpr_realloc(sb->base_slices, new_capacity * sizeof(grpc_slice)));
}
sb->slices = sb->base_slices + slice_offset;
}
}
static void maybe_embiggen(grpc_slice_buffer* sb) { static void maybe_embiggen(grpc_slice_buffer* sb) {
if (sb->count == 0) { if (sb->count == 0) {
sb->slices = sb->base_slices; sb->slices = sb->base_slices;
return;
} }
/* How far away from sb->base_slices is sb->slices pointer */ /* How far away from sb->base_slices is sb->slices pointer */
size_t slice_offset = static_cast<size_t>(sb->slices - sb->base_slices); size_t slice_offset = static_cast<size_t>(sb->slices - sb->base_slices);
size_t slice_count = sb->count + slice_offset; size_t slice_count = sb->count + slice_offset;
if (GPR_UNLIKELY(slice_count == sb->capacity)) {
if (slice_count == sb->capacity) { do_embiggen(sb, slice_count, slice_offset);
if (sb->base_slices != sb->slices) {
/* Make room by moving elements if there's still space unused */
memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
sb->slices = sb->base_slices;
} else {
/* Allocate more memory if no more space is available */
sb->capacity = GROW(sb->capacity);
GPR_ASSERT(sb->capacity > slice_count);
if (sb->base_slices == sb->inlined) {
sb->base_slices = static_cast<grpc_slice*>(
gpr_malloc(sb->capacity * sizeof(grpc_slice)));
memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
} else {
sb->base_slices = static_cast<grpc_slice*>(
gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice)));
}
sb->slices = sb->base_slices + slice_offset;
}
} }
} }

@ -222,7 +222,12 @@ void grpc_mdctx_global_shutdown() {
abort(); abort();
} }
} }
// For ASAN builds, we don't want to crash here, because that will
// prevent ASAN from providing leak detection information, which is
// far more useful than this simple assertion.
#ifndef GRPC_ASAN_ENABLED
GPR_DEBUG_ASSERT(shard->count == 0); GPR_DEBUG_ASSERT(shard->count == 0);
#endif
gpr_free(shard->elems); gpr_free(shard->elems);
} }
} }

@ -90,7 +90,7 @@ void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs,
#endif #endif
GRPC_CLOSURE_INIT(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx);
new (&refcount->refs) grpc_core::RefCount(); new (&refcount->refs) grpc_core::RefCount(1, &grpc_trace_stream_refcount);
new (&refcount->slice_refcount) grpc_slice_refcount( new (&refcount->slice_refcount) grpc_slice_refcount(
grpc_slice_refcount::Type::REGULAR, &refcount->refs, slice_stream_destroy, grpc_slice_refcount::Type::REGULAR, &refcount->refs, slice_stream_destroy,
refcount, &refcount->slice_refcount); refcount, &refcount->slice_refcount);

@ -80,11 +80,13 @@ inline void grpc_stream_ref(grpc_stream_refcount* refcount,
gpr_log(GPR_DEBUG, "%s %p:%p REF %s", refcount->object_type, refcount, gpr_log(GPR_DEBUG, "%s %p:%p REF %s", refcount->object_type, refcount,
refcount->destroy.cb_arg, reason); refcount->destroy.cb_arg, reason);
} }
refcount->refs.RefNonZero(DEBUG_LOCATION, reason);
}
#else #else
inline void grpc_stream_ref(grpc_stream_refcount* refcount) { inline void grpc_stream_ref(grpc_stream_refcount* refcount) {
#endif
refcount->refs.RefNonZero(); refcount->refs.RefNonZero();
} }
#endif
void grpc_stream_destroy(grpc_stream_refcount* refcount); void grpc_stream_destroy(grpc_stream_refcount* refcount);
@ -95,13 +97,17 @@ inline void grpc_stream_unref(grpc_stream_refcount* refcount,
gpr_log(GPR_DEBUG, "%s %p:%p UNREF %s", refcount->object_type, refcount, gpr_log(GPR_DEBUG, "%s %p:%p UNREF %s", refcount->object_type, refcount,
refcount->destroy.cb_arg, reason); refcount->destroy.cb_arg, reason);
} }
if (GPR_UNLIKELY(refcount->refs.Unref(DEBUG_LOCATION, reason))) {
grpc_stream_destroy(refcount);
}
}
#else #else
inline void grpc_stream_unref(grpc_stream_refcount* refcount) { inline void grpc_stream_unref(grpc_stream_refcount* refcount) {
#endif
if (GPR_UNLIKELY(refcount->refs.Unref())) { if (GPR_UNLIKELY(refcount->refs.Unref())) {
grpc_stream_destroy(refcount); grpc_stream_destroy(refcount);
} }
} }
#endif
/* Wrap a buffer that is owned by some stream object into a slice that shares /* Wrap a buffer that is owned by some stream object into a slice that shares
the same refcount */ the same refcount */

@ -51,9 +51,6 @@
case GRPCCompressGzip: case GRPCCompressGzip:
hostConfig.compressAlgorithm = GRPC_COMPRESS_GZIP; hostConfig.compressAlgorithm = GRPC_COMPRESS_GZIP;
break; break;
case GRPCStreamCompressGzip:
hostConfig.compressAlgorithm = GRPC_COMPRESS_STREAM_GZIP;
break;
default: default:
NSLog(@"Invalid compression algorithm"); NSLog(@"Invalid compression algorithm");
abort(); abort();

@ -156,8 +156,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) {
// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // 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 // 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. // 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 // Negative values are not allowed.
// corresponding parameter to the internal default value.
@property(readonly) NSTimeInterval keepaliveInterval; @property(readonly) NSTimeInterval keepaliveInterval;
@property(readonly) NSTimeInterval keepaliveTimeout; @property(readonly) NSTimeInterval keepaliveTimeout;
@ -321,7 +320,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) {
// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the // 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. // 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 // Negative values are invalid; setting these parameters to negative value will reset the
// corresponding parameter to the internal default value. // corresponding parameter to 0.
@property(readwrite) NSTimeInterval keepaliveInterval; @property(readwrite) NSTimeInterval keepaliveInterval;
@property(readwrite) NSTimeInterval keepaliveTimeout; @property(readwrite) NSTimeInterval keepaliveTimeout;

@ -30,7 +30,7 @@ static const NSUInteger kDefaultResponseSizeLimit = 0;
static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone;
static const BOOL kDefaultRetryEnabled = YES; static const BOOL kDefaultRetryEnabled = YES;
static const NSTimeInterval kDefaultKeepaliveInterval = 0; static const NSTimeInterval kDefaultKeepaliveInterval = 0;
static const NSTimeInterval kDefaultKeepaliveTimeout = -1; static const NSTimeInterval kDefaultKeepaliveTimeout = 0;
static const NSTimeInterval kDefaultConnectMinTimeout = 0; static const NSTimeInterval kDefaultConnectMinTimeout = 0;
static const NSTimeInterval kDefaultConnectInitialBackoff = 0; static const NSTimeInterval kDefaultConnectInitialBackoff = 0;
static const NSTimeInterval kDefaultConnectMaxBackoff = 0; static const NSTimeInterval kDefaultConnectMaxBackoff = 0;
@ -181,7 +181,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
_compressionAlgorithm = compressionAlgorithm; _compressionAlgorithm = compressionAlgorithm;
_retryEnabled = retryEnabled; _retryEnabled = retryEnabled;
_keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval; _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval;
_keepaliveTimeout = keepaliveTimeout; _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout;
_connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout; _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout;
_connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff;
_connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff;
@ -486,7 +486,11 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
} }
- (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout {
_keepaliveTimeout = keepaliveTimeout; if (keepaliveTimeout < 0) {
_keepaliveTimeout = 0;
} else {
_keepaliveTimeout = keepaliveTimeout;
}
} }
- (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout {

@ -109,8 +109,6 @@
if (_callOptions.keepaliveInterval != 0) { if (_callOptions.keepaliveInterval != 0) {
args[@GRPC_ARG_KEEPALIVE_TIME_MS] = args[@GRPC_ARG_KEEPALIVE_TIME_MS] =
[NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)];
}
if (_callOptions.keepaliveTimeout >= 0) {
args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] =
[NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)];
} }

@ -118,7 +118,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30;
_lastTimedDestroy = nil; _lastTimedDestroy = nil;
grpc_call *unmanagedCall = grpc_call *unmanagedCall =
[_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; [_wrappedChannel unmanagedCallWithPath:path
completionQueue:[GRPCCompletionQueue completionQueue]
callOptions:callOptions];
if (unmanagedCall == NULL) { if (unmanagedCall == NULL) {
NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object");
return nil; return nil;

@ -105,11 +105,11 @@ static NSMutableDictionary *gHostCache;
options.responseSizeLimit = _responseSizeLimitOverride; options.responseSizeLimit = _responseSizeLimitOverride;
options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm;
options.retryEnabled = _retryEnabled; options.retryEnabled = _retryEnabled;
options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000.0; options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000;
options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000.0; options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000;
options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000.0; options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000;
options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000.0; options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000;
options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000.0; options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000;
options.PEMRootCertificates = _PEMRootCertificates; options.PEMRootCertificates = _PEMRootCertificates;
options.PEMPrivateKey = _PEMPrivateKey; options.PEMPrivateKey = _PEMPrivateKey;
options.PEMCertificateChain = _PEMCertificateChain; options.PEMCertificateChain = _PEMCertificateChain;

@ -48,10 +48,6 @@ static int32_t kRemoteInteropServerOverhead = 12;
return YES; return YES;
} }
+ (BOOL)canRunCompressionTest {
return NO;
}
- (int32_t)encodingOverhead { - (int32_t)encodingOverhead {
return kRemoteInteropServerOverhead; // bytes return kRemoteInteropServerOverhead; // bytes
} }

@ -64,10 +64,4 @@
*/ */
+ (BOOL)useCronet; + (BOOL)useCronet;
/**
* Whether we can run compression tests in the test suite.
*/
+ (BOOL)canRunCompressionTest;
@end @end

@ -347,10 +347,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
return NO; return NO;
} }
+ (BOOL)canRunCompressionTest {
return YES;
}
+ (void)setUp { + (void)setUp {
#ifdef GRPC_COMPILE_WITH_CRONET #ifdef GRPC_COMPILE_WITH_CRONET
configureCronet(); configureCronet();
@ -434,16 +430,10 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
__block BOOL messageReceived = NO; __block BOOL messageReceived = NO;
__block BOOL done = NO; __block BOOL done = NO;
__block BOOL initialMetadataReceived = YES;
NSCondition *cond = [[NSCondition alloc] init]; NSCondition *cond = [[NSCondition alloc] init];
GRPCUnaryProtoCall *call = [_service GRPCUnaryProtoCall *call = [_service
emptyCallWithMessage:request emptyCallWithMessage:request
responseHandler:[[InteropTestsBlockCallbacks alloc] responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[cond lock];
initialMetadataReceived = YES;
[cond unlock];
}
messageCallback:^(id message) { messageCallback:^(id message) {
if (message) { if (message) {
id expectedResponse = [GPBEmpty message]; id expectedResponse = [GPBEmpty message];
@ -469,7 +459,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
while (!done && [deadline timeIntervalSinceNow] > 0) { while (!done && [deadline timeIntervalSinceNow] > 0) {
[cond waitUntilDate:deadline]; [cond waitUntilDate:deadline];
} }
XCTAssertTrue(initialMetadataReceived);
XCTAssertTrue(messageReceived); XCTAssertTrue(messageReceived);
XCTAssertTrue(done); XCTAssertTrue(done);
[cond unlock]; [cond unlock];
@ -1025,78 +1014,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
} }
- (void)testInitialMetadataWithV2API {
__weak XCTestExpectation *initialMetadataReceived =
[self expectationWithDescription:@"Received initial metadata."];
__weak XCTestExpectation *closeReceived = [self expectationWithDescription:@"RPC completed."];
__block NSDictionary *init_md =
[NSDictionary dictionaryWithObjectsAndKeys:@"FOOBAR", @"x-grpc-test-echo-initial", nil];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.initialMetadata = init_md;
options.transportType = self.class.transportType;
options.PEMRootCertificates = self.class.PEMRootCertificates;
options.hostNameOverride = [[self class] hostNameOverride];
RMTSimpleRequest *request = [RMTSimpleRequest message];
__block bool init_md_received = NO;
GRPCUnaryProtoCall *call = [_service
unaryCallWithMessage:request
responseHandler:[[InteropTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
XCTAssertEqualObjects(initialMetadata[@"x-grpc-test-echo-initial"],
init_md[@"x-grpc-test-echo-initial"]);
init_md_received = YES;
[initialMetadataReceived fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
XCTAssertNil(error, @"Unexpected error: %@", error);
[closeReceived fulfill];
}]
callOptions:options];
[call start];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testTrailingMetadataWithV2API {
// This test needs to be disabled for remote test because interop server grpc-test
// does not send trailing binary metadata.
if (isRemoteInteropTest([[self class] host])) {
return;
}
__weak XCTestExpectation *expectation =
[self expectationWithDescription:@"Received trailing metadata."];
const unsigned char raw_bytes[] = {0x1, 0x2, 0x3, 0x4};
NSData *trailer_data = [NSData dataWithBytes:raw_bytes length:sizeof(raw_bytes)];
__block NSDictionary *trailer = [NSDictionary
dictionaryWithObjectsAndKeys:trailer_data, @"x-grpc-test-echo-trailing-bin", nil];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.initialMetadata = trailer;
options.transportType = self.class.transportType;
options.PEMRootCertificates = self.class.PEMRootCertificates;
options.hostNameOverride = [[self class] hostNameOverride];
RMTSimpleRequest *request = [RMTSimpleRequest message];
GRPCUnaryProtoCall *call = [_service
unaryCallWithMessage:request
responseHandler:
[[InteropTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata,
NSError *error) {
XCTAssertNil(error, @"Unexpected error: %@", error);
XCTAssertEqualObjects(
trailingMetadata[@"x-grpc-test-echo-trailing-bin"],
trailer[@"x-grpc-test-echo-trailing-bin"]);
[expectation fulfill];
}]
callOptions:options];
[call start];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testCancelAfterFirstResponseRPC { - (void)testCancelAfterFirstResponseRPC {
XCTAssertNotNil([[self class] host]); XCTAssertNotNil([[self class] host]);
__weak XCTestExpectation *expectation = __weak XCTestExpectation *expectation =
@ -1231,7 +1148,13 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
} }
- (void)RPCWithCompressMethod:(GRPCCompressionAlgorithm)compressMethod { - (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])) {
return;
}
XCTAssertNotNil([[self class] host]);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"];
RMTSimpleRequest *request = [RMTSimpleRequest message]; RMTSimpleRequest *request = [RMTSimpleRequest message];
@ -1239,7 +1162,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
request.responseSize = 314159; request.responseSize = 314159;
request.payload.body = [NSMutableData dataWithLength:271828]; request.payload.body = [NSMutableData dataWithLength:271828];
request.expectCompressed.value = YES; request.expectCompressed.value = YES;
[GRPCCall setDefaultCompressMethod:compressMethod forhost:[[self class] host]]; [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:[[self class] host]];
[_service unaryCallWithRequest:request [_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) { handler:^(RMTSimpleResponse *response, NSError *error) {
@ -1256,67 +1179,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
} }
- (void)RPCWithCompressMethodWithV2API:(GRPCCompressionAlgorithm)compressMethod {
__weak XCTestExpectation *expectMessage =
[self expectationWithDescription:@"Reived response from server."];
__weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"RPC completed."];
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseType = RMTPayloadType_Compressable;
request.responseSize = 314159;
request.payload.body = [NSMutableData dataWithLength:271828];
request.expectCompressed.value = YES;
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = self.class.transportType;
options.PEMRootCertificates = self.class.PEMRootCertificates;
options.hostNameOverride = [[self class] hostNameOverride];
options.compressionAlgorithm = compressMethod;
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);
[expectMessage fulfill];
}
}
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
XCTAssertNil(error, @"Unexpected error: %@", error);
[expectComplete fulfill];
}]
callOptions:options];
[call start];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testCompressedUnaryRPC {
if ([[self class] canRunCompressionTest]) {
for (GRPCCompressionAlgorithm compress = GRPCCompressDeflate;
compress <= GRPCStreamCompressGzip; ++compress) {
[self RPCWithCompressMethod:compress];
}
}
}
- (void)testCompressedUnaryRPCWithV2API {
if ([[self class] canRunCompressionTest]) {
for (GRPCCompressionAlgorithm compress = GRPCCompressDeflate;
compress <= GRPCStreamCompressGzip; ++compress) {
[self RPCWithCompressMethodWithV2API:compress];
}
}
}
#ifndef GRPC_COMPILE_WITH_CRONET #ifndef GRPC_COMPILE_WITH_CRONET
- (void)testKeepalive { - (void)testKeepalive {
XCTAssertNotNil([[self class] host]); XCTAssertNotNil([[self class] host]);
@ -1358,40 +1220,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
} }
- (void)testKeepaliveWithV2API {
XCTAssertNotNil([[self class] host]);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = self.class.transportType;
options.PEMRootCertificates = self.class.PEMRootCertificates;
options.hostNameOverride = [[self class] hostNameOverride];
options.keepaliveInterval = 1.5;
options.keepaliveTimeout = 0;
id request =
[RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415];
__block GRPCStreamingProtoCall *call = [_service
fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
closeCallback:^(
NSDictionary *trailingMetadata,
NSError *error) {
XCTAssertNotNil(error);
XCTAssertEqual(
error.code,
GRPC_STATUS_UNAVAILABLE);
[expectation fulfill];
}]
callOptions:options];
[call start];
[call writeMessage:request];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
#endif #endif
- (void)testDefaultInterceptor { - (void)testDefaultInterceptor {

@ -49,10 +49,6 @@ static int32_t kRemoteInteropServerOverhead = 12;
return nil; return nil;
} }
+ (BOOL)canRunCompressionTest {
return NO;
}
- (int32_t)encodingOverhead { - (int32_t)encodingOverhead {
return kRemoteInteropServerOverhead; // bytes return kRemoteInteropServerOverhead; // bytes
} }

@ -29,7 +29,7 @@
#import <grpc/grpc.h> #import <grpc/grpc.h>
#import <grpc/support/log.h> #import <grpc/support/log.h>
#define TEST_TIMEOUT 64 #define TEST_TIMEOUT 32
extern const char *kCFStreamVarName; extern const char *kCFStreamVarName;
@ -136,11 +136,7 @@ extern const char *kCFStreamVarName;
return GRPCTransportTypeChttp2BoringSSL; return GRPCTransportTypeChttp2BoringSSL;
} }
- (int)getRandomNumberBetween:(int)min max:(int)max { - (void)testNetworkFlapWithV2API {
return min + arc4random_uniform((max - min + 1));
}
- (void)testNetworkFlapOnUnaryCallWithV2API {
NSMutableArray *completeExpectations = [NSMutableArray array]; NSMutableArray *completeExpectations = [NSMutableArray array];
NSMutableArray *calls = [NSMutableArray array]; NSMutableArray *calls = [NSMutableArray array];
int num_rpcs = 100; int num_rpcs = 100;
@ -179,7 +175,6 @@ extern const char *kCFStreamVarName;
UTF8String]); UTF8String]);
address_removed = YES; address_removed = YES;
} else if (error != nil && !address_readded) { } else if (error != nil && !address_readded) {
XCTAssertTrue(address_removed);
system([ system([
[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [NSString stringWithFormat:@"sudo ifconfig lo0 alias %@",
[[self class] hostAddress]] [[self class] hostAddress]]
@ -201,241 +196,7 @@ extern const char *kCFStreamVarName;
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
} }
- (void)testNetworkFlapOnClientStreamingCallWithV2API { - (void)testNetworkFlapWithV1API {
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]]];
GRPCStreamingProtoCall *call = [_service
streamingInputCallWithResponseHandler:
[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
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) {
XCTAssertTrue(address_removed);
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) {
GRPCStreamingProtoCall *call = calls[i];
[call start];
RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message];
request1.payload.body = [NSMutableData dataWithLength:27182];
RMTStreamingInputCallRequest *request2 = [RMTStreamingInputCallRequest message];
request2.payload.body = [NSMutableData dataWithLength:8];
[call writeMessage:request1];
[NSThread sleepForTimeInterval:0.1f];
[call writeMessage:request2];
[call finish];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testNetworkFlapOnServerStreamingCallWithV2API {
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]]];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
for (int i = 0; i < 5; i++) {
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = 10000;
[request.responseParametersArray addObject:parameters];
}
request.payload.body = [NSMutableData dataWithLength:100];
GRPCUnaryProtoCall *call = [_service
streamingOutputCallWithMessage:request
responseHandler:
[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
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) {
XCTAssertTrue(address_removed);
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) {
GRPCStreamingProtoCall *call = calls[i];
[call start];
[NSThread sleepForTimeInterval:0.1f];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testNetworkFlapOnHalfDuplexCallWithV2API {
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]]];
GRPCStreamingProtoCall *call = [_service
halfDuplexCallWithResponseHandler:
[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
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) {
XCTAssertTrue(address_removed);
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) {
GRPCStreamingProtoCall *call = calls[i];
[call start];
RMTStreamingOutputCallRequest *request1 = [RMTStreamingOutputCallRequest message];
RMTStreamingOutputCallRequest *request2 = [RMTStreamingOutputCallRequest message];
for (int i = 0; i < 5; i++) {
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = 1000;
[request1.responseParametersArray addObject:parameters];
[request2.responseParametersArray addObject:parameters];
}
request1.payload.body = [NSMutableData dataWithLength:100];
request2.payload.body = [NSMutableData dataWithLength:100];
[call writeMessage:request1];
[NSThread sleepForTimeInterval:0.1f];
[call writeMessage:request2];
[call finish];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testNetworkFlapOnFullDuplexCallWithV2API {
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]]];
GRPCStreamingProtoCall *call = [_service
fullDuplexCallWithResponseHandler:
[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
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) {
XCTAssertTrue(address_removed);
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) {
GRPCStreamingProtoCall *call = calls[i];
[call start];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = 1000;
for (int i = 0; i < 5; i++) {
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:100];
[call writeMessage:request];
}
[call finish];
[NSThread sleepForTimeInterval:0.1f];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testNetworkFlapOnUnaryCallWithV1API {
NSMutableArray *completeExpectations = [NSMutableArray array]; NSMutableArray *completeExpectations = [NSMutableArray array];
int num_rpcs = 100; int num_rpcs = 100;
__block BOOL address_removed = FALSE; __block BOOL address_removed = FALSE;
@ -459,7 +220,6 @@ extern const char *kCFStreamVarName;
UTF8String]); UTF8String]);
address_removed = YES; address_removed = YES;
} else if (error != nil && !address_readded) { } else if (error != nil && !address_readded) {
XCTAssertTrue(address_removed);
system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@",
[[self class] hostAddress]] [[self class] hostAddress]]
UTF8String]); UTF8String]);
@ -474,141 +234,4 @@ extern const char *kCFStreamVarName;
} }
} }
- (void)testTimeoutOnFullDuplexCallWithV2API {
NSMutableArray *completeExpectations = [NSMutableArray array];
NSMutableArray *calls = [NSMutableArray array];
int num_rpcs = 100;
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = [[self class] transportType];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
options.timeout = 0.3;
for (int i = 0; i < num_rpcs; ++i) {
[completeExpectations
addObject:[self expectationWithDescription:
[NSString stringWithFormat:@"Received trailer for RPC %d", i]]];
GRPCStreamingProtoCall *call = [_service
fullDuplexCallWithResponseHandler:
[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
if (error != nil) {
XCTAssertEqual(error.code, GRPC_STATUS_DEADLINE_EXCEEDED);
}
[completeExpectations[i] fulfill];
}]
callOptions:options];
[calls addObject:call];
}
for (int i = 0; i < num_rpcs; ++i) {
GRPCStreamingProtoCall *call = calls[i];
[call start];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = 1000;
// delay response by 100-200 milliseconds
parameters.intervalUs = [self getRandomNumberBetween:100 * 1000 max:200 * 1000];
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:100];
[call writeMessage:request];
[call writeMessage:request];
[call finish];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testServerStreamingCallSlowClientWithV2API {
NSMutableArray *completeExpectations = [NSMutableArray array];
NSMutableArray *calls = [NSMutableArray array];
int num_rpcs = 100;
dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < num_rpcs; ++i) {
[completeExpectations
addObject:[self expectationWithDescription:
[NSString stringWithFormat:@"Received trailer for RPC %d", i]]];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
for (int i = 0; i < 5; i++) {
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = 10000;
[request.responseParametersArray addObject:parameters];
[request.responseParametersArray addObject:parameters];
[request.responseParametersArray addObject:parameters];
[request.responseParametersArray addObject:parameters];
[request.responseParametersArray addObject:parameters];
}
request.payload.body = [NSMutableData dataWithLength:100];
GRPCUnaryProtoCall *call = [_service
streamingOutputCallWithMessage:request
responseHandler:[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:^(id message) {
// inject a delay
[NSThread sleepForTimeInterval:0.5f];
}
closeCallback:^(NSDictionary *trailingMetadata,
NSError *error) {
XCTAssertNil(error, @"Unexpected error: %@", error);
[completeExpectations[i] fulfill];
}]
callOptions:nil];
[calls addObject:call];
}
for (int i = 0; i < num_rpcs; ++i) {
dispatch_async(q, ^{
GRPCStreamingProtoCall *call = calls[i];
[call start];
});
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testCancelOnFullDuplexCallWithV2API {
NSMutableArray *completeExpectations = [NSMutableArray array];
NSMutableArray *calls = [NSMutableArray array];
int num_rpcs = 100;
dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < num_rpcs; ++i) {
[completeExpectations
addObject:[self expectationWithDescription:
[NSString stringWithFormat:@"Received trailer for RPC %d", i]]];
GRPCStreamingProtoCall *call = [_service
fullDuplexCallWithResponseHandler:[[MacTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
closeCallback:^(
NSDictionary *trailingMetadata,
NSError *error) {
[completeExpectations[i] fulfill];
}]
callOptions:nil];
[calls addObject:call];
}
for (int i = 0; i < num_rpcs; ++i) {
GRPCStreamingProtoCall *call = calls[i];
[call start];
dispatch_async(q, ^{
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = 1000;
for (int i = 0; i < 100; i++) {
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
[request.responseParametersArray addObject:parameters];
[call writeMessage:request];
}
[NSThread sleepForTimeInterval:0.01f];
[call cancel];
});
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@end @end

@ -21,11 +21,6 @@
#import <RemoteTest/Messages.pbobjc.h> #import <RemoteTest/Messages.pbobjc.h>
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#import "../../GRPCClient/private/GRPCCallInternal.h"
#import "../../GRPCClient/private/GRPCChannel.h"
#import "../../GRPCClient/private/GRPCChannelPool.h"
#import "../../GRPCClient/private/GRPCWrappedCall.h"
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
@ -53,41 +48,12 @@ static const int kSimpleDataLength = 100;
static const NSTimeInterval kTestTimeout = 8; static const NSTimeInterval kTestTimeout = 8;
static const NSTimeInterval kInvertedTimeout = 2; static const NSTimeInterval kInvertedTimeout = 2;
// Reveal the _class ivars for testing access // Reveal the _class ivar for testing access
@interface GRPCCall2 () { @interface GRPCCall2 () {
@public
id<GRPCInterceptorInterface> _firstInterceptor;
}
@end
@interface GRPCCall2Internal () {
@public @public
GRPCCall *_call; GRPCCall *_call;
} }
@end
@interface GRPCCall () {
@public
GRPCWrappedCall *_wrappedCall;
}
@end
@interface GRPCWrappedCall () {
@public
GRPCPooledChannel *_pooledChannel;
}
@end
@interface GRPCPooledChannel () {
@public
GRPCChannel *_wrappedChannel;
}
@end
@interface GRPCChannel () {
@public
grpc_channel *_unmanagedChannel;
}
@end @end
// Convenience class to use blocks as callbacks // Convenience class to use blocks as callbacks
@ -182,7 +148,6 @@ static const NSTimeInterval kInvertedTimeout = 2;
kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
service:kService service:kService
method:@"StreamingOutputCall"]; method:@"StreamingOutputCall"];
kFullDuplexCallMethod = kFullDuplexCallMethod =
[[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"];
} }
@ -214,7 +179,7 @@ static const NSTimeInterval kInvertedTimeout = 2;
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
trailing_md = trailingMetadata; trailing_md = trailingMetadata;
if (error) { if (error) {
XCTAssertEqual(error.code, GRPCErrorCodeUnauthenticated, XCTAssertEqual(error.code, 16,
@"Finished with unexpected error: %@", error); @"Finished with unexpected error: %@", error);
XCTAssertEqualObjects(init_md, XCTAssertEqualObjects(init_md,
error.userInfo[kGRPCHeadersKey]); error.userInfo[kGRPCHeadersKey]);
@ -794,7 +759,7 @@ static const NSTimeInterval kInvertedTimeout = 2;
} }
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
XCTAssertNotNil(error, @"Expecting non-nil error"); XCTAssertNotNil(error, @"Expecting non-nil error");
XCTAssertEqual(error.code, GRPCErrorCodeUnknown); XCTAssertEqual(error.code, 2);
[completion fulfill]; [completion fulfill];
}] }]
callOptions:options]; callOptions:options];
@ -805,293 +770,4 @@ static const NSTimeInterval kInvertedTimeout = 2;
[self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
} }
- (void)testAdditionalChannelArgs {
__weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
GRPCRequestOptions *requestOptions =
[[GRPCRequestOptions alloc] initWithHost:kHostAddress
path:kUnaryCallMethod.HTTPPath
safety:GRPCCallSafetyDefault];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
// set max message length = 1 byte.
options.additionalChannelArgs =
[NSDictionary dictionaryWithObjectsAndKeys:@1, @GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, nil];
options.transportType = GRPCTransportTypeInsecure;
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit];
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");
NSLog(@"Got error: %@", error);
XCTAssertEqual(error.code, GRPCErrorCodeResourceExhausted,
@"Finished with unexpected error: %@", error);
[completion fulfill];
}]
callOptions:options];
[call writeData:[request data]];
[call start];
[call finish];
[self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
}
- (void)testChannelReuseIdentical {
__weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."];
__weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."];
NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil];
__weak XCTestExpectation *metadata1 =
[self expectationWithDescription:@"Received initial metadata for RPC1."];
__weak XCTestExpectation *metadata2 =
[self expectationWithDescription:@"Received initial metadata for RPC2."];
NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = kSimpleDataLength;
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
GRPCRequestOptions *requestOptions =
[[GRPCRequestOptions alloc] initWithHost:kHostAddress
path:kFullDuplexCallMethod.HTTPPath
safety:GRPCCallSafetyDefault];
GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init];
callOptions.transportType = GRPCTransportTypeInsecure;
GRPCCall2 *call1 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata1 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion1 fulfill];
}]
callOptions:callOptions];
GRPCCall2 *call2 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata2 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion2 fulfill];
}]
callOptions:callOptions];
[call1 start];
[call2 start];
[call1 writeData:[request data]];
[call2 writeData:[request data]];
[self waitForExpectations:initialMetadataDone timeout:kTestTimeout];
GRPCCall2Internal *internalCall1 = call1->_firstInterceptor;
GRPCCall2Internal *internalCall2 = call2->_firstInterceptor;
XCTAssertEqual(
internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel,
internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel);
[call1 finish];
[call2 finish];
[self waitForExpectations:rpcDone timeout:kTestTimeout];
}
- (void)testChannelReuseDifferentCallSafety {
__weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."];
__weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."];
NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil];
__weak XCTestExpectation *metadata1 =
[self expectationWithDescription:@"Received initial metadata for RPC1."];
__weak XCTestExpectation *metadata2 =
[self expectationWithDescription:@"Received initial metadata for RPC2."];
NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = kSimpleDataLength;
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
GRPCRequestOptions *requestOptions1 =
[[GRPCRequestOptions alloc] initWithHost:kHostAddress
path:kFullDuplexCallMethod.HTTPPath
safety:GRPCCallSafetyDefault];
GRPCRequestOptions *requestOptions2 =
[[GRPCRequestOptions alloc] initWithHost:kHostAddress
path:kFullDuplexCallMethod.HTTPPath
safety:GRPCCallSafetyIdempotentRequest];
GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init];
callOptions.transportType = GRPCTransportTypeInsecure;
GRPCCall2 *call1 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions1
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata1 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion1 fulfill];
}]
callOptions:callOptions];
GRPCCall2 *call2 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions2
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata2 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion2 fulfill];
}]
callOptions:callOptions];
[call1 start];
[call2 start];
[call1 writeData:[request data]];
[call2 writeData:[request data]];
[self waitForExpectations:initialMetadataDone timeout:kTestTimeout];
GRPCCall2Internal *internalCall1 = call1->_firstInterceptor;
GRPCCall2Internal *internalCall2 = call2->_firstInterceptor;
XCTAssertEqual(
internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel,
internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel);
[call1 finish];
[call2 finish];
[self waitForExpectations:rpcDone timeout:kTestTimeout];
}
- (void)testChannelReuseDifferentHost {
__weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."];
__weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."];
NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil];
__weak XCTestExpectation *metadata1 =
[self expectationWithDescription:@"Received initial metadata for RPC1."];
__weak XCTestExpectation *metadata2 =
[self expectationWithDescription:@"Received initial metadata for RPC2."];
NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = kSimpleDataLength;
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
GRPCRequestOptions *requestOptions1 =
[[GRPCRequestOptions alloc] initWithHost:@"[::1]:5050"
path:kFullDuplexCallMethod.HTTPPath
safety:GRPCCallSafetyDefault];
GRPCRequestOptions *requestOptions2 =
[[GRPCRequestOptions alloc] initWithHost:@"127.0.0.1:5050"
path:kFullDuplexCallMethod.HTTPPath
safety:GRPCCallSafetyDefault];
GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init];
callOptions.transportType = GRPCTransportTypeInsecure;
GRPCCall2 *call1 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions1
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata1 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion1 fulfill];
}]
callOptions:callOptions];
GRPCCall2 *call2 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions2
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata2 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion2 fulfill];
}]
callOptions:callOptions];
[call1 start];
[call2 start];
[call1 writeData:[request data]];
[call2 writeData:[request data]];
[self waitForExpectations:initialMetadataDone timeout:kTestTimeout];
GRPCCall2Internal *internalCall1 = call1->_firstInterceptor;
GRPCCall2Internal *internalCall2 = call2->_firstInterceptor;
XCTAssertNotEqual(
internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel,
internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel);
[call1 finish];
[call2 finish];
[self waitForExpectations:rpcDone timeout:kTestTimeout];
}
- (void)testChannelReuseDifferentChannelArgs {
__weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."];
__weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."];
NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil];
__weak XCTestExpectation *metadata1 =
[self expectationWithDescription:@"Received initial metadata for RPC1."];
__weak XCTestExpectation *metadata2 =
[self expectationWithDescription:@"Received initial metadata for RPC2."];
NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = kSimpleDataLength;
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
GRPCRequestOptions *requestOptions =
[[GRPCRequestOptions alloc] initWithHost:kHostAddress
path:kFullDuplexCallMethod.HTTPPath
safety:GRPCCallSafetyDefault];
GRPCMutableCallOptions *callOptions1 = [[GRPCMutableCallOptions alloc] init];
callOptions1.transportType = GRPCTransportTypeInsecure;
GRPCMutableCallOptions *callOptions2 = [[GRPCMutableCallOptions alloc] init];
callOptions2.transportType = GRPCTransportTypeInsecure;
callOptions2.channelID = 2;
GRPCCall2 *call1 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata1 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion1 fulfill];
}]
callOptions:callOptions1];
GRPCCall2 *call2 = [[GRPCCall2 alloc]
initWithRequestOptions:requestOptions
responseHandler:[[ClientTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) {
[metadata2 fulfill];
}
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
[completion2 fulfill];
}]
callOptions:callOptions2];
[call1 start];
[call2 start];
[call1 writeData:[request data]];
[call2 writeData:[request data]];
[self waitForExpectations:initialMetadataDone timeout:kTestTimeout];
GRPCCall2Internal *internalCall1 = call1->_firstInterceptor;
GRPCCall2Internal *internalCall2 = call2->_firstInterceptor;
XCTAssertNotEqual(
internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel,
internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel);
[call1 finish];
[call2 finish];
[self waitForExpectations:rpcDone timeout:kTestTimeout];
}
@end @end

@ -0,0 +1,28 @@
%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.
<%include file="../../python_stretch.include"/>
RUN apt-get install -y jq zlib1g-dev libssl-dev
COPY get_cpython.sh /tmp
RUN apt-get install -y jq build-essential libffi-dev && ${'\\'}
chmod +x /tmp/get_cpython.sh && ${'\\'}
/tmp/get_cpython.sh && ${'\\'}
rm /tmp/get_cpython.sh
RUN python3.8 -m ensurepip && ${'\\'}
python3.8 -m pip install coverage

@ -45,7 +45,7 @@ def main():
{ {
'name': 'bad_client_test', 'name': 'bad_client_test',
'build': 'private', 'build': 'private',
'language': 'c', 'language': 'c++',
'src': [ 'src': [
'test/core/bad_client/bad_client.cc' 'test/core/bad_client/bad_client.cc'
], ],
@ -64,7 +64,7 @@ def main():
'name': '%s_bad_client_test' % t, 'name': '%s_bad_client_test' % t,
'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost, 'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost,
'build': 'test', 'build': 'test',
'language': 'c', 'language': 'c++',
'secure': 'no', 'secure': 'no',
'src': ['test/core/bad_client/tests/%s.cc' % t], 'src': ['test/core/bad_client/tests/%s.cc' % t],
'vs_proj_dir': 'test', 'vs_proj_dir': 'test',

@ -42,6 +42,10 @@ def grpc_bad_client_tests():
name = 'bad_client_test', name = 'bad_client_test',
srcs = ['bad_client.cc'], srcs = ['bad_client.cc'],
hdrs = ['bad_client.h'], hdrs = ['bad_client.h'],
external_deps = [
"gtest",
],
language = "C++",
deps = ['//test/core/util:grpc_test_util', '//:grpc', '//:gpr', '//test/core/end2end:cq_verifier'] deps = ['//test/core/util:grpc_test_util', '//:grpc', '//:gpr', '//test/core/end2end:cq_verifier']
) )
for t, topt in BAD_CLIENT_TESTS.items(): for t, topt in BAD_CLIENT_TESTS.items():

@ -16,13 +16,14 @@
* *
*/ */
#include <string>
#include <gtest/gtest.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/surface/server.h" #include "src/core/lib/surface/server.h"
#include "test/core/bad_client/bad_client.h" #include "test/core/bad_client/bad_client.h"
#define PFX_STR \
"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
"\x00\x00\x00\x04\x00\x00\x00\x00\x00"
static void verifier(grpc_server* server, grpc_completion_queue* cq, static void verifier(grpc_server* server, grpc_completion_queue* cq,
void* registered_method) { void* registered_method) {
while (grpc_server_has_open_connections(server)) { while (grpc_server_has_open_connections(server)) {
@ -32,15 +33,33 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
} }
} }
#define APPEND_BUFFER(string, to_append) \
((string).append((to_append), sizeof(to_append) - 1))
namespace {
TEST(UnknownFrameType, Test) {
/* test that all invalid/unknown frame types are handled */
for (int i = 10; i <= 255; i++) {
std::string unknown_frame_string;
APPEND_BUFFER(unknown_frame_string, "\x00\x00\x00");
char frame_type = static_cast<char>(i);
unknown_frame_string.append(&frame_type, 1);
APPEND_BUFFER(unknown_frame_string, "\x00\x00\x00\x00\x01");
grpc_bad_client_arg args[2];
args[0] = connection_preface_arg;
args[1].client_validator = nullptr;
args[1].client_payload = unknown_frame_string.c_str();
args[1].client_payload_length = unknown_frame_string.size();
grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT);
}
}
} // namespace
int main(int argc, char** argv) { int main(int argc, char** argv) {
grpc_init(); grpc_init();
grpc::testing::TestEnvironment env(argc, argv); grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
/* test adding prioritization data */ int retval = RUN_ALL_TESTS();
GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr,
PFX_STR "\x00\x00\x00\x88\x00\x00\x00\x00\x01",
GRPC_BAD_CLIENT_DISCONNECT);
grpc_shutdown(); grpc_shutdown();
return 0; return retval;
} }

@ -437,6 +437,35 @@ TEST_F(MapTest, LowerBound) {
EXPECT_EQ(it, test_map.end()); EXPECT_EQ(it, test_map.end());
} }
// Test move ctor
TEST_F(MapTest, MoveCtor) {
Map<const char*, Payload, StringLess> test_map;
for (int i = 0; i < 5; i++) {
test_map.emplace(kKeys[i], Payload(i));
}
Map<const char*, Payload, StringLess> test_map2 = std::move(test_map);
for (int i = 0; i < 5; i++) {
EXPECT_EQ(test_map.end(), test_map.find(kKeys[i]));
EXPECT_EQ(i, test_map2.find(kKeys[i])->second.data());
}
}
// Test move assignment
TEST_F(MapTest, MoveAssignment) {
Map<const char*, Payload, StringLess> test_map;
for (int i = 0; i < 5; i++) {
test_map.emplace(kKeys[i], Payload(i));
}
Map<const char*, Payload, StringLess> test_map2;
test_map2.emplace("xxx", Payload(123));
test_map2 = std::move(test_map);
for (int i = 0; i < 5; i++) {
EXPECT_EQ(test_map.end(), test_map.find(kKeys[i]));
EXPECT_EQ(i, test_map2.find(kKeys[i])->second.data());
}
EXPECT_EQ(test_map2.end(), test_map2.find("xxx"));
}
} // namespace testing } // namespace testing
} // namespace grpc_core } // namespace grpc_core

@ -117,7 +117,7 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy
PickResult Pick(PickArgs args) override { PickResult Pick(PickArgs args) override {
PickResult result = delegate_picker_->Pick(args); PickResult result = delegate_picker_->Pick(args);
if (result.type == PickResult::PICK_COMPLETE && if (result.type == PickResult::PICK_COMPLETE &&
result.connected_subchannel != nullptr) { result.subchannel != nullptr) {
new (args.call_state->Alloc(sizeof(TrailingMetadataHandler))) new (args.call_state->Alloc(sizeof(TrailingMetadataHandler)))
TrailingMetadataHandler(&result, cb_, user_data_); TrailingMetadataHandler(&result, cb_, user_data_);
} }

@ -118,8 +118,7 @@ bool CheckExpectedCompression(const ServerContext& context,
"Expected compression but got uncompressed request from client."); "Expected compression but got uncompressed request from client.");
return false; return false;
} }
if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS) && if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)) {
received_compression != GRPC_COMPRESS_STREAM_GZIP) {
gpr_log(GPR_ERROR, gpr_log(GPR_ERROR,
"Failure: Requested compression in a compressable request, but " "Failure: Requested compression in a compressable request, but "
"compression bit in message flags not set."); "compression bit in message flags not set.");

@ -0,0 +1,79 @@
# 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 debian:stretch
# 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
# 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
# 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 install -y jq zlib1g-dev libssl-dev
COPY get_cpython.sh /tmp
RUN apt-get install -y jq build-essential libffi-dev && \
chmod +x /tmp/get_cpython.sh && \
/tmp/get_cpython.sh && \
rm /tmp/get_cpython.sh
RUN python3.8 -m ensurepip && \
python3.8 -m pip install coverage

@ -0,0 +1,29 @@
#!/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.
VERSION_REGEX="v3.8.*"
REPO="python/cpython"
LATEST=$(curl -s https://api.github.com/repos/$REPO/tags | \
jq -r '.[] | select(.name|test("'$VERSION_REGEX'")) | .name' \
| sort | tail -n1)
wget https://github.com/$REPO/archive/$LATEST.tar.gz
tar xzvf *.tar.gz
( cd cpython*
./configure
make install
)

@ -5292,7 +5292,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "badreq_bad_client_test", "name": "badreq_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/badreq.cc" "test/core/bad_client/tests/badreq.cc"
@ -5309,7 +5309,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "connection_prefix_bad_client_test", "name": "connection_prefix_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/connection_prefix.cc" "test/core/bad_client/tests/connection_prefix.cc"
@ -5326,7 +5326,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "duplicate_header_bad_client_test", "name": "duplicate_header_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/duplicate_header.cc" "test/core/bad_client/tests/duplicate_header.cc"
@ -5343,7 +5343,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "head_of_line_blocking_bad_client_test", "name": "head_of_line_blocking_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/head_of_line_blocking.cc" "test/core/bad_client/tests/head_of_line_blocking.cc"
@ -5360,7 +5360,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "headers_bad_client_test", "name": "headers_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/headers.cc" "test/core/bad_client/tests/headers.cc"
@ -5377,7 +5377,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "initial_settings_frame_bad_client_test", "name": "initial_settings_frame_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/initial_settings_frame.cc" "test/core/bad_client/tests/initial_settings_frame.cc"
@ -5394,7 +5394,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "large_metadata_bad_client_test", "name": "large_metadata_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/large_metadata.cc" "test/core/bad_client/tests/large_metadata.cc"
@ -5411,7 +5411,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "server_registered_method_bad_client_test", "name": "server_registered_method_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/server_registered_method.cc" "test/core/bad_client/tests/server_registered_method.cc"
@ -5428,7 +5428,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "simple_request_bad_client_test", "name": "simple_request_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/simple_request.cc" "test/core/bad_client/tests/simple_request.cc"
@ -5445,7 +5445,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "unknown_frame_bad_client_test", "name": "unknown_frame_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/unknown_frame.cc" "test/core/bad_client/tests/unknown_frame.cc"
@ -5462,7 +5462,7 @@
], ],
"headers": [], "headers": [],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "window_overflow_bad_client_test", "name": "window_overflow_bad_client_test",
"src": [ "src": [
"test/core/bad_client/tests/window_overflow.cc" "test/core/bad_client/tests/window_overflow.cc"
@ -7756,7 +7756,7 @@
"test/core/bad_client/bad_client.h" "test/core/bad_client/bad_client.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c", "language": "c++",
"name": "bad_client_test", "name": "bad_client_test",
"src": [ "src": [
"test/core/bad_client/bad_client.cc", "test/core/bad_client/bad_client.cc",

@ -5958,7 +5958,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "badreq_bad_client_test", "name": "badreq_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -5984,7 +5984,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "connection_prefix_bad_client_test", "name": "connection_prefix_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6010,7 +6010,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "duplicate_header_bad_client_test", "name": "duplicate_header_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6036,7 +6036,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "head_of_line_blocking_bad_client_test", "name": "head_of_line_blocking_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6062,7 +6062,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "headers_bad_client_test", "name": "headers_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6088,7 +6088,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "initial_settings_frame_bad_client_test", "name": "initial_settings_frame_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6114,7 +6114,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "large_metadata_bad_client_test", "name": "large_metadata_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6140,7 +6140,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "server_registered_method_bad_client_test", "name": "server_registered_method_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6166,7 +6166,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "simple_request_bad_client_test", "name": "simple_request_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6192,7 +6192,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "unknown_frame_bad_client_test", "name": "unknown_frame_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",
@ -6218,7 +6218,7 @@
], ],
"flaky": false, "flaky": false,
"gtest": false, "gtest": false,
"language": "c", "language": "c++",
"name": "window_overflow_bad_client_test", "name": "window_overflow_bad_client_test",
"platforms": [ "platforms": [
"linux", "linux",

@ -753,7 +753,7 @@ class PythonLanguage(object):
def _python_manager_name(self): def _python_manager_name(self):
"""Choose the docker image to use based on python version.""" """Choose the docker image to use based on python version."""
if self.args.compiler in [ if self.args.compiler in [
'python2.7', 'python3.5', 'python3.6', 'python3.7' 'python2.7', 'python3.5', 'python3.6', 'python3.7', 'python3.8'
]: ]:
return 'stretch_' + self.args.compiler[len('python'):] return 'stretch_' + self.args.compiler[len('python'):]
elif self.args.compiler == 'python_alpine': elif self.args.compiler == 'python_alpine':
@ -829,6 +829,12 @@ class PythonLanguage(object):
minor='7', minor='7',
bits=bits, bits=bits,
config_vars=config_vars) config_vars=config_vars)
python38_config = _python_config_generator(
name='py38',
major='3',
minor='8',
bits=bits,
config_vars=config_vars)
pypy27_config = _pypy_config_generator( pypy27_config = _pypy_config_generator(
name='pypy', major='2', config_vars=config_vars) name='pypy', major='2', config_vars=config_vars)
pypy32_config = _pypy_config_generator( pypy32_config = _pypy_config_generator(
@ -852,6 +858,8 @@ class PythonLanguage(object):
return (python36_config,) return (python36_config,)
elif args.compiler == 'python3.7': elif args.compiler == 'python3.7':
return (python37_config,) return (python37_config,)
elif args.compiler == 'python3.8':
return (python38_config,)
elif args.compiler == 'pypy': elif args.compiler == 'pypy':
return (pypy27_config,) return (pypy27_config,)
elif args.compiler == 'pypy3': elif args.compiler == 'pypy3':
@ -865,6 +873,7 @@ class PythonLanguage(object):
python35_config, python35_config,
python36_config, python36_config,
python37_config, python37_config,
# TODO: Add Python 3.8 once it's released.
) )
else: else:
raise Exception('Compiler %s not supported.' % args.compiler) raise Exception('Compiler %s not supported.' % args.compiler)
@ -1340,9 +1349,10 @@ argp.add_argument(
choices=[ choices=[
'default', 'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc7.2', 'default', 'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc7.2',
'gcc_musl', 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7', 'clang7.0', 'gcc_musl', 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7', 'clang7.0',
'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7', 'pypy', 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7',
'pypy3', 'python_alpine', 'all_the_cpythons', 'electron1.3', 'python3.8', 'pypy', 'pypy3', 'python_alpine', 'all_the_cpythons',
'electron1.6', 'coreclr', 'cmake', 'cmake_vs2015', 'cmake_vs2017' 'electron1.3', 'electron1.6', 'coreclr', 'cmake', 'cmake_vs2015',
'cmake_vs2017'
], ],
default='default', default='default',
help= help=

Loading…
Cancel
Save