diff --git a/.pylintrc b/.pylintrc index da2081b87e1..41027479061 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,34 +1,40 @@ +[VARIABLES] +# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection +# not include "unused_" and "ignored_" by default? +dummy-variables-rgx=^ignored_|^unused_ + +[DESIGN] +# NOTE(nathaniel): Not particularly attached to this value; it just seems to +# be what works for us at the moment (excepting the dead-code-walking Beta +# API). +max-args=6 + +[MISCELLANEOUS] +# NOTE(nathaniel): We are big fans of "TODO(): " and +# "NOTE(): ". We do not allow "TODO:", +# "TODO():", "FIXME:", or anything else. +notes=FIXME,XXX + [MESSAGES CONTROL] #TODO: Enable missing-docstring #TODO: Enable too-few-public-methods -#TODO: Enable too-many-arguments #TODO: Enable no-init #TODO: Enable duplicate-code #TODO: Enable invalid-name -#TODO: Enable suppressed-message #TODO: Enable locally-disabled #TODO: Enable protected-access #TODO: Enable no-name-in-module -#TODO: Enable unused-argument -#TODO: Enable fixme #TODO: Enable wrong-import-order -#TODO: Enable no-value-for-parameter -#TODO: Enable cyclic-import -#TODO: Enable unused-variable -#TODO: Enable redefined-outer-name -#TODO: Enable unused-import +# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279): +# enable cyclic-import after a 1.7-or-later pylint release that recognizes our +# disable=cyclic-import suppressions. #TODO: Enable too-many-instance-attributes -#TODO: Enable broad-except -#TODO: Enable too-many-locals #TODO: Enable too-many-lines #TODO: Enable redefined-variable-type #TODO: Enable next-method-called #TODO: Enable import-error #TODO: Enable useless-else-on-loop -#TODO: Enable too-many-return-statements #TODO: Enable too-many-nested-blocks -#TODO: Enable super-init-not-called -#TODO: Enable no-self-use -disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,fixme,wrong-import-order,no-value-for-parameter,cyclic-import,unused-variable,redefined-outer-name,unused-import,too-many-instance-attributes,broad-except,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called,no-self-use +disable=missing-docstring,too-few-public-methods,no-init,duplicate-code,invalid-name,locally-disabled,protected-access,no-name-in-module,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-nested-blocks diff --git a/BUILD b/BUILD index 6c8291f09dd..ca0a1c56076 100644 --- a/BUILD +++ b/BUILD @@ -127,7 +127,6 @@ grpc_cc_library( "src/cpp/server/secure_server_credentials.cc", ], hdrs = [ - "include/grpc++/impl/codegen/core_codegen.h", "src/cpp/client/secure_credentials.h", "src/cpp/common/secure_auth_context.h", "src/cpp/server/secure_server_credentials.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 94d578eebda..ec41db75e0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,6 +353,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c dualstack_socket_test) endif() add_dependencies(buildtests_c endpoint_pair_test) +add_dependencies(buildtests_c error_test) if(_gRPC_PLATFORM_LINUX) add_dependencies(buildtests_c ev_epoll_linux_test) endif() @@ -440,6 +441,7 @@ add_dependencies(buildtests_c mlog_test) add_dependencies(buildtests_c multiple_server_queues_test) add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) +add_dependencies(buildtests_c parse_address_test) add_dependencies(buildtests_c percent_encoding_test) if(_gRPC_PLATFORM_LINUX) add_dependencies(buildtests_c pollset_set_test) @@ -464,6 +466,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c socket_utils_test) endif() add_dependencies(buildtests_c status_conversion_test) +add_dependencies(buildtests_c stream_owned_slice_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c tcp_client_posix_test) endif() @@ -586,7 +589,16 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_error) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_cxx bm_fullstack) +add_dependencies(buildtests_cxx bm_fullstack_streaming_ping_pong) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_fullstack_streaming_pump) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_fullstack_trickle) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_fullstack_unary_ping_pong) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_metadata) @@ -651,6 +663,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test) endif() add_dependencies(buildtests_cxx server_builder_plugin_test) +add_dependencies(buildtests_cxx server_builder_test) add_dependencies(buildtests_cxx server_context_test_spouse_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx server_crash_test) @@ -1438,7 +1451,7 @@ add_library(grpc_test_util test/core/security/oauth2_utils.c test/core/end2end/cq_verifier.c test/core/end2end/fake_resolver.c - test/core/end2end/fixtures/http_proxy.c + test/core/end2end/fixtures/http_proxy_fixture.c test/core/end2end/fixtures/proxy.c test/core/iomgr/endpoint_tests.c test/core/util/debugger_macros.c @@ -1447,10 +1460,8 @@ add_library(grpc_test_util test/core/util/mock_endpoint.c test/core/util/parse_hexstring.c test/core/util/passthru_endpoint.c - test/core/util/port_posix.c + test/core/util/port.c test/core/util/port_server_client.c - test/core/util/port_uv.c - test/core/util/port_windows.c test/core/util/slice_splitter.c test/core/util/trickle_endpoint.c src/core/lib/channel/channel_args.c @@ -1647,7 +1658,7 @@ if (gRPC_BUILD_TESTS) add_library(grpc_test_util_unsecure test/core/end2end/cq_verifier.c test/core/end2end/fake_resolver.c - test/core/end2end/fixtures/http_proxy.c + test/core/end2end/fixtures/http_proxy_fixture.c test/core/end2end/fixtures/proxy.c test/core/iomgr/endpoint_tests.c test/core/util/debugger_macros.c @@ -1656,10 +1667,8 @@ add_library(grpc_test_util_unsecure test/core/util/mock_endpoint.c test/core/util/parse_hexstring.c test/core/util/passthru_endpoint.c - test/core/util/port_posix.c + test/core/util/port.c test/core/util/port_server_client.c - test/core/util/port_uv.c - test/core/util/port_windows.c test/core/util/slice_splitter.c test/core/util/trickle_endpoint.c ) @@ -2078,6 +2087,7 @@ add_library(grpc++ src/cpp/common/rpc_method.cc src/cpp/common/version_cc.cc src/cpp/server/async_generic_service.cc + src/cpp/server/channel_argument_option.cc src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc @@ -2143,6 +2153,7 @@ foreach(_hdr include/grpc++/grpc++.h include/grpc++/health_check_service_interface.h include/grpc++/impl/call.h + include/grpc++/impl/channel_argument_option.h include/grpc++/impl/client_unary_call.h include/grpc++/impl/codegen/core_codegen.h include/grpc++/impl/grpc_library.h @@ -2264,6 +2275,7 @@ add_library(grpc++_cronet src/cpp/common/rpc_method.cc src/cpp/common/version_cc.cc src/cpp/server/async_generic_service.cc + src/cpp/server/channel_argument_option.cc src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc @@ -2513,6 +2525,7 @@ foreach(_hdr include/grpc++/grpc++.h include/grpc++/health_check_service_interface.h include/grpc++/impl/call.h + include/grpc++/impl/channel_argument_option.h include/grpc++/impl/client_unary_call.h include/grpc++/impl/codegen/core_codegen.h include/grpc++/impl/grpc_library.h @@ -2935,6 +2948,7 @@ add_library(grpc++_unsecure src/cpp/common/rpc_method.cc src/cpp/common/version_cc.cc src/cpp/server/async_generic_service.cc + src/cpp/server/channel_argument_option.cc src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc @@ -3000,6 +3014,7 @@ foreach(_hdr include/grpc++/grpc++.h include/grpc++/health_check_service_interface.h include/grpc++/impl/call.h + include/grpc++/impl/channel_argument_option.h include/grpc++/impl/client_unary_call.h include/grpc++/impl/codegen/core_codegen.h include/grpc++/impl/grpc_library.h @@ -3100,6 +3115,50 @@ endif() if (gRPC_BUILD_TESTS) +add_library(grpc_benchmark + test/cpp/microbenchmarks/helpers.cc +) + +if(WIN32 AND MSVC) + set_target_properties(grpc_benchmark PROPERTIES COMPILE_PDB_NAME "grpc_benchmark" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_benchmark.pdb + DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(grpc_benchmark + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${ZLIB_INCLUDE_DIR} + PRIVATE ${BENCHMARK}/include + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/include + PRIVATE third_party/googletest + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_benchmark + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark + grpc++ + grpc_test_util + grpc + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_library(grpc_cli_libs test/cpp/util/cli_call.cc test/cpp/util/cli_credentials.cc @@ -4562,6 +4621,33 @@ target_link_libraries(endpoint_pair_test gpr ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(error_test + test/core/iomgr/error_test.c +) + + +target_include_directories(error_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include +) + +target_link_libraries(error_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) @@ -6443,6 +6529,33 @@ target_link_libraries(no_server_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(parse_address_test + test/core/client_channel/parse_address_test.c +) + + +target_include_directories(parse_address_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include +) + +target_link_libraries(parse_address_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(percent_encoding_test test/core/slice/percent_encoding_test.c ) @@ -6933,6 +7046,33 @@ target_link_libraries(status_conversion_test gpr ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(stream_owned_slice_test + test/core/transport/stream_owned_slice_test.c +) + + +target_include_directories(stream_owned_slice_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include +) + +target_link_libraries(stream_owned_slice_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -7509,6 +7649,7 @@ target_include_directories(bm_call_create target_link_libraries(bm_call_create ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark grpc++_test_util grpc_test_util @@ -7547,6 +7688,7 @@ target_include_directories(bm_chttp2_hpack target_link_libraries(bm_chttp2_hpack ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark grpc++_test_util grpc_test_util @@ -7585,6 +7727,7 @@ target_include_directories(bm_closure target_link_libraries(bm_closure ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark grpc++_test_util grpc_test_util @@ -7623,6 +7766,7 @@ target_include_directories(bm_cq target_link_libraries(bm_cq ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark grpc++_test_util grpc_test_util @@ -7661,6 +7805,85 @@ target_include_directories(bm_error target_link_libraries(bm_error ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + benchmark + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_fullstack_streaming_ping_pong + test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc + third_party/googletest/src/gtest-all.cc +) + + +target_include_directories(bm_fullstack_streaming_ping_pong + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/include + PRIVATE third_party/googletest + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bm_fullstack_streaming_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + benchmark + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_fullstack_streaming_pump + test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc + third_party/googletest/src/gtest-all.cc +) + + +target_include_directories(bm_fullstack_streaming_pump + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/include + PRIVATE third_party/googletest + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bm_fullstack_streaming_pump + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark grpc++_test_util grpc_test_util @@ -7676,13 +7899,13 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(bm_fullstack - test/cpp/microbenchmarks/bm_fullstack.cc +add_executable(bm_fullstack_trickle + test/cpp/microbenchmarks/bm_fullstack_trickle.cc third_party/googletest/src/gtest-all.cc ) -target_include_directories(bm_fullstack +target_include_directories(bm_fullstack_trickle PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include @@ -7696,9 +7919,49 @@ target_include_directories(bm_fullstack PRIVATE ${_gRPC_PROTO_GENS_DIR} ) -target_link_libraries(bm_fullstack +target_link_libraries(bm_fullstack_trickle ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + benchmark + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_fullstack_unary_ping_pong + test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc + third_party/googletest/src/gtest-all.cc +) + + +target_include_directories(bm_fullstack_unary_ping_pong + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/include + PRIVATE third_party/googletest + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bm_fullstack_unary_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark grpc++_test_util grpc_test_util @@ -7737,8 +8000,11 @@ target_include_directories(bm_metadata target_link_libraries(bm_metadata ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark benchmark + grpc++_test_util grpc_test_util + grpc++ grpc gpr_test_util gpr @@ -9610,6 +9876,55 @@ target_link_libraries(server_builder_plugin_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(server_builder_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + test/cpp/server/server_builder_test.cc + third_party/googletest/src/gtest-all.cc +) + +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/echo_messages.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/echo.proto +) + +target_include_directories(server_builder_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/include + PRIVATE third_party/googletest + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_builder_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + gpr_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(server_context_test_spouse_test test/cpp/test/server_context_test_spouse_test.cc third_party/googletest/src/gtest-all.cc diff --git a/Makefile b/Makefile index 57e877beb01..534728dc8e9 100644 --- a/Makefile +++ b/Makefile @@ -926,6 +926,7 @@ dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_te dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test +error_test: $(BINDIR)/$(CONFIG)/error_test ev_epoll_linux_test: $(BINDIR)/$(CONFIG)/ev_epoll_linux_test fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test fd_posix_test: $(BINDIR)/$(CONFIG)/fd_posix_test @@ -1002,6 +1003,7 @@ murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test no_server_test: $(BINDIR)/$(CONFIG)/no_server_test +parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test @@ -1024,6 +1026,7 @@ sockaddr_utils_test: $(BINDIR)/$(CONFIG)/sockaddr_utils_test socket_utils_test: $(BINDIR)/$(CONFIG)/socket_utils_test ssl_server_fuzzer: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer status_conversion_test: $(BINDIR)/$(CONFIG)/status_conversion_test +stream_owned_slice_test: $(BINDIR)/$(CONFIG)/stream_owned_slice_test tcp_client_posix_test: $(BINDIR)/$(CONFIG)/tcp_client_posix_test tcp_client_uv_test: $(BINDIR)/$(CONFIG)/tcp_client_uv_test tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test @@ -1049,7 +1052,10 @@ bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack bm_closure: $(BINDIR)/$(CONFIG)/bm_closure bm_cq: $(BINDIR)/$(CONFIG)/bm_cq bm_error: $(BINDIR)/$(CONFIG)/bm_error -bm_fullstack: $(BINDIR)/$(CONFIG)/bm_fullstack +bm_fullstack_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong +bm_fullstack_streaming_pump: $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump +bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle +bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test @@ -1100,6 +1106,7 @@ round_robin_end2end_test: $(BINDIR)/$(CONFIG)/round_robin_end2end_test secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test +server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client @@ -1297,6 +1304,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/dns_resolver_test \ $(BINDIR)/$(CONFIG)/dualstack_socket_test \ $(BINDIR)/$(CONFIG)/endpoint_pair_test \ + $(BINDIR)/$(CONFIG)/error_test \ $(BINDIR)/$(CONFIG)/ev_epoll_linux_test \ $(BINDIR)/$(CONFIG)/fd_conservation_posix_test \ $(BINDIR)/$(CONFIG)/fd_posix_test \ @@ -1360,6 +1368,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/multiple_server_queues_test \ $(BINDIR)/$(CONFIG)/murmur_hash_test \ $(BINDIR)/$(CONFIG)/no_server_test \ + $(BINDIR)/$(CONFIG)/parse_address_test \ $(BINDIR)/$(CONFIG)/percent_encoding_test \ $(BINDIR)/$(CONFIG)/pollset_set_test \ $(BINDIR)/$(CONFIG)/resolve_address_posix_test \ @@ -1378,6 +1387,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/sockaddr_utils_test \ $(BINDIR)/$(CONFIG)/socket_utils_test \ $(BINDIR)/$(CONFIG)/status_conversion_test \ + $(BINDIR)/$(CONFIG)/stream_owned_slice_test \ $(BINDIR)/$(CONFIG)/tcp_client_posix_test \ $(BINDIR)/$(CONFIG)/tcp_client_uv_test \ $(BINDIR)/$(CONFIG)/tcp_posix_test \ @@ -1463,7 +1473,10 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_closure \ $(BINDIR)/$(CONFIG)/bm_cq \ $(BINDIR)/$(CONFIG)/bm_error \ - $(BINDIR)/$(CONFIG)/bm_fullstack \ + $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong \ + $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump \ + $(BINDIR)/$(CONFIG)/bm_fullstack_trickle \ + $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -1507,6 +1520,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ $(BINDIR)/$(CONFIG)/server_builder_plugin_test \ + $(BINDIR)/$(CONFIG)/server_builder_test \ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \ $(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ @@ -1574,7 +1588,10 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_closure \ $(BINDIR)/$(CONFIG)/bm_cq \ $(BINDIR)/$(CONFIG)/bm_error \ - $(BINDIR)/$(CONFIG)/bm_fullstack \ + $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong \ + $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump \ + $(BINDIR)/$(CONFIG)/bm_fullstack_trickle \ + $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -1618,6 +1635,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ $(BINDIR)/$(CONFIG)/server_builder_plugin_test \ + $(BINDIR)/$(CONFIG)/server_builder_test \ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \ $(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ @@ -1683,6 +1701,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/dualstack_socket_test || ( echo test dualstack_socket_test failed ; exit 1 ) $(E) "[RUN] Testing endpoint_pair_test" $(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 ) + $(E) "[RUN] Testing error_test" + $(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 ) $(E) "[RUN] Testing ev_epoll_linux_test" $(Q) $(BINDIR)/$(CONFIG)/ev_epoll_linux_test || ( echo test ev_epoll_linux_test failed ; exit 1 ) $(E) "[RUN] Testing fd_conservation_posix_test" @@ -1793,6 +1813,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/murmur_hash_test || ( echo test murmur_hash_test failed ; exit 1 ) $(E) "[RUN] Testing no_server_test" $(Q) $(BINDIR)/$(CONFIG)/no_server_test || ( echo test no_server_test failed ; exit 1 ) + $(E) "[RUN] Testing parse_address_test" + $(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 ) $(E) "[RUN] Testing percent_encoding_test" $(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 ) $(E) "[RUN] Testing pollset_set_test" @@ -1829,6 +1851,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/socket_utils_test || ( echo test socket_utils_test failed ; exit 1 ) $(E) "[RUN] Testing status_conversion_test" $(Q) $(BINDIR)/$(CONFIG)/status_conversion_test || ( echo test status_conversion_test failed ; exit 1 ) + $(E) "[RUN] Testing stream_owned_slice_test" + $(Q) $(BINDIR)/$(CONFIG)/stream_owned_slice_test || ( echo test stream_owned_slice_test failed ; exit 1 ) $(E) "[RUN] Testing tcp_client_posix_test" $(Q) $(BINDIR)/$(CONFIG)/tcp_client_posix_test || ( echo test tcp_client_posix_test failed ; exit 1 ) $(E) "[RUN] Testing tcp_client_uv_test" @@ -1909,8 +1933,14 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_cq || ( echo test bm_cq failed ; exit 1 ) $(E) "[RUN] Testing bm_error" $(Q) $(BINDIR)/$(CONFIG)/bm_error || ( echo test bm_error failed ; exit 1 ) - $(E) "[RUN] Testing bm_fullstack" - $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack || ( echo test bm_fullstack failed ; exit 1 ) + $(E) "[RUN] Testing bm_fullstack_streaming_ping_pong" + $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong || ( echo test bm_fullstack_streaming_ping_pong failed ; exit 1 ) + $(E) "[RUN] Testing bm_fullstack_streaming_pump" + $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump || ( echo test bm_fullstack_streaming_pump failed ; exit 1 ) + $(E) "[RUN] Testing bm_fullstack_trickle" + $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_trickle || ( echo test bm_fullstack_trickle failed ; exit 1 ) + $(E) "[RUN] Testing bm_fullstack_unary_ping_pong" + $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong || ( echo test bm_fullstack_unary_ping_pong failed ; exit 1 ) $(E) "[RUN] Testing bm_metadata" $(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 ) $(E) "[RUN] Testing channel_arguments_test" @@ -1971,6 +2001,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 ) $(E) "[RUN] Testing server_builder_plugin_test" $(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 ) + $(E) "[RUN] Testing server_builder_test" + $(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 ) $(E) "[RUN] Testing server_context_test_spouse_test" $(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 ) $(E) "[RUN] Testing server_crash_test" @@ -3310,7 +3342,7 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/security/oauth2_utils.c \ test/core/end2end/cq_verifier.c \ test/core/end2end/fake_resolver.c \ - test/core/end2end/fixtures/http_proxy.c \ + test/core/end2end/fixtures/http_proxy_fixture.c \ test/core/end2end/fixtures/proxy.c \ test/core/iomgr/endpoint_tests.c \ test/core/util/debugger_macros.c \ @@ -3319,10 +3351,8 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/util/mock_endpoint.c \ test/core/util/parse_hexstring.c \ test/core/util/passthru_endpoint.c \ - test/core/util/port_posix.c \ + test/core/util/port.c \ test/core/util/port_server_client.c \ - test/core/util/port_uv.c \ - test/core/util/port_windows.c \ test/core/util/slice_splitter.c \ test/core/util/trickle_endpoint.c \ src/core/lib/channel/channel_args.c \ @@ -3512,7 +3542,7 @@ endif LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/end2end/cq_verifier.c \ test/core/end2end/fake_resolver.c \ - test/core/end2end/fixtures/http_proxy.c \ + test/core/end2end/fixtures/http_proxy_fixture.c \ test/core/end2end/fixtures/proxy.c \ test/core/iomgr/endpoint_tests.c \ test/core/util/debugger_macros.c \ @@ -3521,10 +3551,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/util/mock_endpoint.c \ test/core/util/parse_hexstring.c \ test/core/util/passthru_endpoint.c \ - test/core/util/port_posix.c \ + test/core/util/port.c \ test/core/util/port_server_client.c \ - test/core/util/port_uv.c \ - test/core/util/port_windows.c \ test/core/util/slice_splitter.c \ test/core/util/trickle_endpoint.c \ @@ -3919,6 +3947,7 @@ LIBGRPC++_SRC = \ src/cpp/common/rpc_method.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ + src/cpp/server/channel_argument_option.cc \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ @@ -3951,6 +3980,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/grpc++.h \ include/grpc++/health_check_service_interface.h \ include/grpc++/impl/call.h \ + include/grpc++/impl/channel_argument_option.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/codegen/core_codegen.h \ include/grpc++/impl/grpc_library.h \ @@ -4118,6 +4148,7 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/common/rpc_method.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ + src/cpp/server/channel_argument_option.cc \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ @@ -4333,6 +4364,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/grpc++.h \ include/grpc++/health_check_service_interface.h \ include/grpc++/impl/call.h \ + include/grpc++/impl/channel_argument_option.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/codegen/core_codegen.h \ include/grpc++/impl/grpc_library.h \ @@ -4801,6 +4833,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/common/rpc_method.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ + src/cpp/server/channel_argument_option.cc \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ @@ -4833,6 +4866,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/grpc++.h \ include/grpc++/health_check_service_interface.h \ include/grpc++/impl/call.h \ + include/grpc++/impl/channel_argument_option.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/codegen/core_codegen.h \ include/grpc++/impl/grpc_library.h \ @@ -4964,6 +4998,55 @@ ifneq ($(NO_DEPS),true) endif +LIBGRPC_BENCHMARK_SRC = \ + test/cpp/microbenchmarks/helpers.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBGRPC_BENCHMARK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_BENCHMARK_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_BENCHMARK_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBGRPC_BENCHMARK_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC_BENCHMARK_OBJS:.o=.dep) +endif +endif + + LIBGRPC_CLI_LIBS_SRC = \ test/cpp/util/cli_call.cc \ test/cpp/util/cli_credentials.cc \ @@ -8651,6 +8734,38 @@ endif endif +ERROR_TEST_SRC = \ + test/core/iomgr/error_test.c \ + +ERROR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ERROR_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/error_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/error_test: $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/error_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_error_test: $(ERROR_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(ERROR_TEST_OBJS:.o=.dep) +endif +endif + + EV_EPOLL_LINUX_TEST_SRC = \ test/core/iomgr/ev_epoll_linux_test.c \ @@ -11083,6 +11198,38 @@ endif endif +PARSE_ADDRESS_TEST_SRC = \ + test/core/client_channel/parse_address_test.c \ + +PARSE_ADDRESS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PARSE_ADDRESS_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/parse_address_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_parse_address_test: $(PARSE_ADDRESS_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PARSE_ADDRESS_TEST_OBJS:.o=.dep) +endif +endif + + PERCENT_DECODE_FUZZER_SRC = \ test/core/slice/percent_decode_fuzzer.c \ @@ -11787,6 +11934,38 @@ endif endif +STREAM_OWNED_SLICE_TEST_SRC = \ + test/core/transport/stream_owned_slice_test.c \ + +STREAM_OWNED_SLICE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STREAM_OWNED_SLICE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/stream_owned_slice_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep) +endif +endif + + TCP_CLIENT_POSIX_TEST_SRC = \ test/core/iomgr/tcp_client_posix_test.c \ @@ -12483,16 +12662,16 @@ $(BINDIR)/$(CONFIG)/bm_call_create: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep) @@ -12526,16 +12705,16 @@ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep) @@ -12569,16 +12748,16 @@ $(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure + $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep) @@ -12612,16 +12791,16 @@ $(BINDIR)/$(CONFIG)/bm_cq: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq + $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bm_cq: $(BM_CQ_OBJS:.o=.dep) @@ -12655,16 +12834,16 @@ $(BINDIR)/$(CONFIG)/bm_error: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error + $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bm_error: $(BM_ERROR_OBJS:.o=.dep) @@ -12675,15 +12854,144 @@ endif endif -BM_FULLSTACK_SRC = \ - test/cpp/microbenchmarks/bm_fullstack.cc \ +BM_FULLSTACK_STREAMING_PING_PONG_SRC = \ + test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc \ + +BM_FULLSTACK_STREAMING_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_STREAMING_PING_PONG_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_bm_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep) +endif +endif + + +BM_FULLSTACK_STREAMING_PUMP_SRC = \ + test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc \ + +BM_FULLSTACK_STREAMING_PUMP_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_STREAMING_PUMP_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_bm_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep) +endif +endif + + +BM_FULLSTACK_TRICKLE_SRC = \ + test/cpp/microbenchmarks/bm_fullstack_trickle.cc \ + +BM_FULLSTACK_TRICKLE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_TRICKLE_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_trickle + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_bm_fullstack_trickle: $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep) +endif +endif + + +BM_FULLSTACK_UNARY_PING_PONG_SRC = \ + test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc \ -BM_FULLSTACK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_SRC)))) +BM_FULLSTACK_UNARY_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_UNARY_PING_PONG_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/bm_fullstack: openssl_dep_error +$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: openssl_dep_error else @@ -12694,26 +13002,26 @@ ifeq ($(NO_PROTOBUF),true) # You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. -$(BINDIR)/$(CONFIG)/bm_fullstack: protobuf_dep_error +$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack: $(PROTOBUF_DEP) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_bm_fullstack: $(BM_FULLSTACK_OBJS:.o=.dep) +deps_bm_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(BM_FULLSTACK_OBJS:.o=.dep) +-include $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep) endif endif @@ -12741,16 +13049,16 @@ $(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata + $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep) @@ -14827,6 +15135,56 @@ endif endif +SERVER_BUILDER_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ + test/cpp/server/server_builder_test.cc \ + +SERVER_BUILDER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/server_builder_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/server_builder_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVER_BUILDER_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc + + SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \ test/cpp/test/server_context_test_spouse_test.cc \ @@ -18192,6 +18550,7 @@ test/cpp/interop/interop_client.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) +test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_sync.cc: $(OPENSSL_DEP) test/cpp/qps/driver.cc: $(OPENSSL_DEP) diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl index 9020eacb740..ab1add476e1 100644 --- a/bazel/cc_grpc_library.bzl +++ b/bazel/cc_grpc_library.bzl @@ -2,7 +2,7 @@ load("//:bazel/generate_cc.bzl", "generate_cc") -def cc_grpc_library(name, srcs, deps, proto_only, **kwargs): +def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_external = False, **kwargs): """Generates C++ grpc classes from a .proto file. Assumes the generated classes will be used in cc_api_version = 2. @@ -12,6 +12,11 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs): srcs: a single proto_library, which wraps the .proto files with services. deps: a list of C++ proto_library (or cc_proto_library) which provides the compiled code of any message that the services depend on. + well_known_protos: The target from protobuf library that exports well + known protos. Currently it will only work if the value is + "@submodule_protobuf//:well_known_protos" + use_external: When True the grpc deps are prefixed with //external. This + allows grpc to be used as a dependency in other bazel projects. **kwargs: rest of arguments, e.g., compatible_with and visibility. """ if len(srcs) > 1: @@ -33,22 +38,37 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs): generate_cc( name = codegen_target, srcs = [proto_target], + well_known_protos = well_known_protos, **kwargs ) if not proto_only: + if use_external: + # when this file is used by non-grpc projects + plugin = "//external:grpc_cpp_plugin" + else: + plugin = "//:grpc_cpp_plugin" + generate_cc( name = codegen_grpc_target, srcs = [proto_target], - plugin = "//:grpc_cpp_plugin", + plugin = plugin, + well_known_protos = well_known_protos, **kwargs ) + if use_external: + # when this file is used by non-grpc projects + grpc_deps = ["//external:grpc++", "//external:grpc++_codegen_proto", + "//external:protobuf"] + else: + grpc_deps = ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"] + native.cc_library( name = name, srcs = [":" + codegen_grpc_target, ":" + codegen_target], hdrs = [":" + codegen_grpc_target, ":" + codegen_target], - deps = deps + ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"], + deps = deps + grpc_deps, **kwargs ) else: diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index d49cbe8d728..f3961f0a419 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -31,8 +31,20 @@ def generate_cc_impl(ctx): arguments += ["-I{0}={0}".format(include.path) for include in includes] arguments += [proto.path for proto in protos] + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/submodule_protobuf/src/google/protobuf": + print("Error: Only @submodule_protobuf//:well_known_protos is supported") + else: + # f points to "external/submodule_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] + ctx.action( - inputs = protos + includes + additional_input, + inputs = protos + includes + additional_input + well_known_proto_files, outputs = out_files, executable = ctx.executable._protoc, arguments = arguments, @@ -56,6 +68,9 @@ generate_cc = rule( mandatory = False, allow_empty = True, ), + "well_known_protos" : attr.label( + mandatory = False, + ), "_protoc": attr.label( default = Label("//external:protocol_compiler"), executable = True, diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index daf8b78527a..8b524bd0e52 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -58,11 +58,14 @@ def grpc_proto_plugin(name, srcs = [], deps = []): load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") -def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True): +def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None, + has_services = True, use_external = False): cc_grpc_library( name = name, srcs = srcs, deps = deps, + well_known_protos = well_known_protos, proto_only = not has_services, + use_external = use_external, ) diff --git a/binding.gyp b/binding.gyp index b8a1a52f502..c521a27c300 100644 --- a/binding.gyp +++ b/binding.gyp @@ -43,7 +43,11 @@ # out. It can be re-enabled for one build by setting the npm config # variable grpc_uv to true, and it can be re-enabled permanently by # setting it to true here. - 'grpc_uv%': 'false' + 'grpc_uv%': 'false', + # Some Node installations use the system installation of OpenSSL, and on + # some systems, the system OpenSSL still does not have ALPN support. This + # will let users recompile gRPC to work without ALPN. + 'grpc_alpn%': 'true' }, 'target_defaults': { 'include_dirs': [ @@ -54,10 +58,8 @@ 'GPR_BACKWARDS_COMPATIBILITY_MODE' ], 'conditions': [ - ['runtime=="node" and grpc_uv=="true"', { + ['grpc_uv=="true"', { 'defines': [ - # Disabling this while bugs are ironed out. Uncomment this to - # re-enable libuv integration in C core. 'GRPC_UV' ] }], @@ -75,10 +77,16 @@ 'OPENSSL_NO_ASM' ] }, { - # As of the beginning of 2017, we only support versions of Node with - # embedded versions of OpenSSL that support ALPN - 'defines': [ - 'TSI_OPENSSL_ALPN_SUPPORT=1' + 'conditions': [ + ['grpc_alpn=="true"', { + 'defines': [ + 'TSI_OPENSSL_ALPN_SUPPORT=1' + ], + }, { + 'defines': [ + 'TSI_OPENSSL_ALPN_SUPPORT=0' + ], + }] ], 'include_dirs': [ '<(node_root_dir)/deps/openssl/openssl/include', diff --git a/build.yaml b/build.yaml index 9ff37d59e17..9c1e3e78462 100644 --- a/build.yaml +++ b/build.yaml @@ -586,7 +586,7 @@ filegroups: headers: - test/core/end2end/cq_verifier.h - test/core/end2end/fake_resolver.h - - test/core/end2end/fixtures/http_proxy.h + - test/core/end2end/fixtures/http_proxy_fixture.h - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h @@ -602,7 +602,7 @@ filegroups: src: - test/core/end2end/cq_verifier.c - test/core/end2end/fake_resolver.c - - test/core/end2end/fixtures/http_proxy.c + - test/core/end2end/fixtures/http_proxy_fixture.c - test/core/end2end/fixtures/proxy.c - test/core/iomgr/endpoint_tests.c - test/core/util/debugger_macros.c @@ -611,10 +611,8 @@ filegroups: - test/core/util/mock_endpoint.c - test/core/util/parse_hexstring.c - test/core/util/passthru_endpoint.c - - test/core/util/port_posix.c + - test/core/util/port.c - test/core/util/port_server_client.c - - test/core/util/port_uv.c - - test/core/util/port_windows.c - test/core/util/slice_splitter.c - test/core/util/trickle_endpoint.c deps: @@ -776,6 +774,7 @@ filegroups: - include/grpc++/grpc++.h - include/grpc++/health_check_service_interface.h - include/grpc++/impl/call.h + - include/grpc++/impl/channel_argument_option.h - include/grpc++/impl/client_unary_call.h - include/grpc++/impl/codegen/core_codegen.h - include/grpc++/impl/grpc_library.h @@ -832,6 +831,7 @@ filegroups: - src/cpp/common/rpc_method.cc - src/cpp/common/version_cc.cc - src/cpp/server/async_generic_service.cc + - src/cpp/server/channel_argument_option.cc - src/cpp/server/create_default_thread_pool.cc - src/cpp/server/dynamic_thread_pool.cc - src/cpp/server/health/default_health_check_service.cc @@ -1216,6 +1216,20 @@ libs: - grpc++_codegen_base_src secure: false vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}' +- name: grpc_benchmark + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/fullstack_context_mutators.h + - test/cpp/microbenchmarks/fullstack_fixtures.h + - test/cpp/microbenchmarks/helpers.h + src: + - test/cpp/microbenchmarks/helpers.cc + deps: + - benchmark + - grpc++ + - grpc_test_util + - grpc - name: grpc_cli_libs build: private language: c++ @@ -1688,6 +1702,17 @@ targets: - gpr exclude_iomgrs: - uv +- name: error_test + cpu_cost: 30 + build: test + language: c + src: + - test/core/iomgr/error_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: ev_epoll_linux_test build: test language: c @@ -2494,6 +2519,16 @@ targets: - grpc - gpr_test_util - gpr +- name: parse_address_test + build: test + language: c + src: + - test/core/client_channel/parse_address_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: percent_decode_fuzzer build: fuzzer language: c @@ -2750,6 +2785,16 @@ targets: - grpc - gpr_test_util - gpr +- name: stream_owned_slice_test + build: test + language: c + src: + - test/core/transport/stream_owned_slice_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: tcp_client_posix_test cpu_cost: 0.5 build: test @@ -3013,6 +3058,7 @@ targets: src: - test/cpp/microbenchmarks/bm_call_create.cc deps: + - grpc_benchmark - benchmark - grpc++_test_util - grpc_test_util @@ -3032,6 +3078,7 @@ targets: src: - test/cpp/microbenchmarks/bm_chttp2_hpack.cc deps: + - grpc_benchmark - benchmark - grpc++_test_util - grpc_test_util @@ -3051,6 +3098,7 @@ targets: src: - test/cpp/microbenchmarks/bm_closure.cc deps: + - grpc_benchmark - benchmark - grpc++_test_util - grpc_test_util @@ -3070,6 +3118,7 @@ targets: src: - test/cpp/microbenchmarks/bm_cq.cc deps: + - grpc_benchmark - benchmark - grpc++_test_util - grpc_test_util @@ -3089,6 +3138,27 @@ targets: src: - test/cpp/microbenchmarks/bm_error.cc deps: + - grpc_benchmark + - benchmark + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + args: + - --benchmark_min_time=0 + platforms: + - mac + - linux + - posix +- name: bm_fullstack_streaming_ping_pong + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc + deps: + - grpc_benchmark - benchmark - grpc++_test_util - grpc_test_util @@ -3098,16 +3168,69 @@ targets: - gpr args: - --benchmark_min_time=0 + excluded_poll_engines: + - poll + - poll-cv platforms: - mac - linux - posix -- name: bm_fullstack + timeout_seconds: 1200 +- name: bm_fullstack_streaming_pump build: test language: c++ src: - - test/cpp/microbenchmarks/bm_fullstack.cc + - test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc deps: + - grpc_benchmark + - benchmark + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + args: + - --benchmark_min_time=0 + excluded_poll_engines: + - poll + - poll-cv + platforms: + - mac + - linux + - posix + timeout_seconds: 1200 +- name: bm_fullstack_trickle + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_fullstack_trickle.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + args: + - --benchmark_min_time=0 + excluded_poll_engines: + - poll + - poll-cv + platforms: + - mac + - linux + - posix + timeout_seconds: 1200 +- name: bm_fullstack_unary_ping_pong + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc + deps: + - grpc_benchmark - benchmark - grpc++_test_util - grpc_test_util @@ -3131,8 +3254,11 @@ targets: src: - test/cpp/microbenchmarks/bm_metadata.cc deps: + - grpc_benchmark - benchmark + - grpc++_test_util - grpc_test_util + - grpc++ - grpc - gpr_test_util - gpr @@ -3343,6 +3469,8 @@ targets: - grpc++ - grpc - gpr + args: + - --generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h - name: grpc_cli build: test run: false @@ -3808,6 +3936,21 @@ targets: - grpc - gpr_test_util - gpr +- name: server_builder_test + gtest: true + build: test + language: c++ + src: + - src/proto/grpc/testing/echo_messages.proto + - src/proto/grpc/testing/echo.proto + - test/cpp/server/server_builder_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - gpr_test_util + - grpc++ + - grpc + - gpr - name: server_context_test_spouse_test gtest: true build: test diff --git a/composer.json b/composer.json index 53ae6388fb4..0cafb94808c 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/doc/PROTOCOL-WEB.md b/doc/PROTOCOL-WEB.md index 35448d683f2..5f01af36273 100644 --- a/doc/PROTOCOL-WEB.md +++ b/doc/PROTOCOL-WEB.md @@ -39,6 +39,7 @@ Content-Type * e.g. application/grpc-web+[proto, json, thrift] 2. application/grpc-web-text * text-encoded streams of “application/grpc-web” + * e.g. application/grpc-web-text+[proto, thrift] --- @@ -60,10 +61,18 @@ HTTP/2 related behavior (specified in [gRPC over HTTP2](http://www.grpc.io/docs/ Message framing (vs. [http2-transport-mapping](http://www.grpc.io/docs/guides/wire.html#http2-transport-mapping)) 1. Response status encoded as part of the response body - * Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline). + * Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline), per https://tools.ietf.org/html/rfc7230#section-3.2 + ``` + key1: foo\r\n + key2: bar\r\n + ``` 2. 8th (MSB) bit of the 1st gRPC frame byte * 0: data * 1: trailers + ``` + 10000000b: an uncompressed trailer (as part of the body) + 10000001b: a compressed trailer + ``` 3. Trailers must be the last message of the response, as enforced by the implementation 4. Trailers-only responses: no change to the gRPC protocol spec. @@ -72,10 +81,9 @@ in the body. --- -User Agent and Server headers +User Agent -* U-A: grpc-web-javascript/0.1 -* Server: grpc-web-gateway/0.1 +* U-A: grpc-web-javascript --- @@ -86,14 +94,12 @@ the response stream needs to be text encoded e.g. when XHR is used or due to security policies with XHR * Accept: application/grpc-web-text 2. The default text encoding is base64 - * Text encoding may be specified with Content-Type or Accept headers as - * application/grpc-web-text-base64 * Note that “Content-Transfer-Encoding: base64” should not be used. Due to in-stream base64 padding when delimiting messages, the entire response body is not necessarily a valid base64-encoded entity * While the server runtime will always base64-encode and flush gRPC messages atomically the client library should not assume base64 padding always - happens at the boundary of message frames. + happens at the boundary of message frames. That is, the implementation may send base64-encoded "chunks" with potential padding whenever the runtime needs to flush a byte buffer. 3. For binary trailers, when the content-type is set to application/grpc-web-text, the extra base64 encoding specified in [gRPC over HTTP2](http://www.grpc.io/docs/guides/wire.html) @@ -131,6 +137,10 @@ Security CORS preflight +* Should follow the [CORS spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control) + * Access-Control-Allow-Credentials to allow Authorization headers + * Access-Control-Allow-Methods to allow POST and (preflight) OPTIONS only + * Access-Control-Allow-Headers to whatever the preflight request carries * The client library may support header overwrites to avoid preflight * https://github.com/whatwg/fetch/issues/210 * CSP support to be specified @@ -149,3 +159,10 @@ Bidi-streaming, with flow-control * Pending on [whatwg fetch/streams](https://github.com/whatwg/fetch) to be finalized and implemented in modern browsers * gRPC-Web client will support the native gRPC protocol with modern browsers + +--- + +Versioning + +* Special headers may be introduced to support features that may break compatiblity. + diff --git a/doc/internationalization.md b/doc/internationalization.md new file mode 100644 index 00000000000..1b614cbd264 --- /dev/null +++ b/doc/internationalization.md @@ -0,0 +1,45 @@ +gRPC Internationalization +========================= + +As a universal RPC framework, gRPC needs to be fully usable within/across different international environments. +This document describes gRPC API and behavior specifics when used in a non-english environment. + +## API Concepts + +While some API elements need to be able to represent non-english content, some are intentionally left as ASCII-only +for simplicity & performance reasons. + +### Method name (in RPC Invocation) +Method names are ASCII-only and may only contain characters allowed by HTTP/2 text header values. That should not +be very limiting as most gRPC services will use protobuf which only allows method names from an even more restricted ASCII subset. +Also, handling method names is a very hot code path so any additional encoding/decoding step is to be avoided. + +Recommended representation in language-specific APIs: string type. + +### Host name (in RPC Invocation) +Host names are punycode encoded, but the user is responsible for providing the punycode-encoded string if she wishes to use an internationalized host name. + +Recommended representation in language-specific APIs: string/unicode string. + +NOTE: overriding host name when invoking RPCs is only supported by C-core based gRPC implementations. + +### Status detail/message (accompanies RPC status code) + +Status messages are expected to contain national-alphabet characters. +Allowed values are unicode strings (content will be percent-encoded on the wire). + +Recommended representation in language-specific APIs: unicode string. + +### Metadata key +Allowed values are defined by HTTP/2 standard (metadata keys are represented as HTTP/2 header/trailer names). + +Recommended representation in language-specific APIs: string. + +### Metadata value (text-valued metadata) +Allowed values are defined by HTTP/2 standard (metadata values are represented as HTTP/2 header/trailer text values). + +Recommended representation in language-specific APIs: string. + +### Channel target (in channel creation) + +TBD diff --git a/doc/server_side_auth.md b/doc/server_side_auth.md new file mode 100644 index 00000000000..288c6e9cb38 --- /dev/null +++ b/doc/server_side_auth.md @@ -0,0 +1,60 @@ +Server-side API for Authenticating Clients +========================================== + +NOTE: This document describes how server-side authentication works in C-core based gRPC implementations only. In gRPC Java and Go, server side authentication is handled differently. + +## AuthContext + +To perform server-side authentication, gRPC exposes the *authentication context* for each call. The context exposes important authentication-related information about the RPC such as the type of security/authentication type being used and the peer identity. + +The authentication context is structured as a multi-map of key-value pairs - the *auth properties*. In addition to that, for authenticated RPCs, the set of properties corresponding to a selected key will represent the verified identity of the caller - the *peer identity*. + +The contents of the *auth properties* are populated by an *auth interceptor*. The interceptor also chooses which property key will act as the peer identity (e.g. for client certificate authentication this property will be `"x509_common_name"` or `"x509_subject_alternative_name"`). + +WARNING: AuthContext is the only reliable source of truth when it comes to authenticating RPCs. Using any other call/context properties for authentication purposes is wrong and inherently unsafe. + +####Example AuthContext contents + +For secure channel using mutual TLS authentication with both client and server certificates (test certificates from this repository are used). + +Populated auth properties: +``` +"transport_security_type": "ssl" # connection is secured using TLS/SSL +"x509_common_name": "*.test.google.com" # from client's certificate +"x509_pem_cert": "-----BEGIN CERTIFICATE-----\n..." # client's PEM encoded certificate +"x509_subject_alternative_name": "*.test.google.fr" +"x509_subject_alternative_name": "waterzooi.test.google.be" +"x509_subject_alternative_name": "*.test.youtube.com" +"x509_subject_alternative_name": "192.168.1.3" +``` + +The peer identity is set of all properties named `"x509_subject_alternative_name"`: +``` +peer_identity_property_name = "x509_subject_alternative_name" +``` + +## AuthProperty + +Auth properties are elements of the AuthContext. They have a name (a key of type string) and a value which can be a string or binary data. + +## Auth Interceptors + +Auth interceptors are gRPC components that populate contents of the auth context based on gRPC's internal state and/or call metadata. +gRPC comes with some basic "interceptors" already built-in. + +WARNING: While there is a public API that allows anyone to write their own custom interceptor, please think twice before using it. +There are legitimate uses for custom interceptors but you should keep in mind that as auth interceptors essentially decide which RPCs are authenticated and which are not, their code is very sensitive from the security perspective and getting things wrong might have serious consequences. If unsure, we strongly recommend to rely on official & proven interceptors that come with gRPC. + +####Available auth interceptors +- TLS/SSL certificate authentication (built into gRPC's security layer, automatically used whenever you use a secure connection) +- (coming soon) JWT auth token authentication +- more will be added over time + +## Status (by language) +C-core exposes low level API to access auth context contents and to implement an auth interceptor. +In C++, the auth interceptor API is exposed as `AuthMetadataProcessor`. + +A high level API to access AuthContext contents is available in these languages: +- C++ +- C# (implementation in-progress) +- other languages coming soon diff --git a/etc/roots.pem b/etc/roots.pem index 79357e01f2b..66605675ef0 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -320,35 +320,6 @@ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m 0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -# Issuer: O=RSA Security Inc OU=RSA Security 2048 V3 -# Subject: O=RSA Security Inc OU=RSA Security 2048 V3 -# Label: "RSA Security 2048 v3" -# Serial: 13297492616345471454730593562152402946 -# MD5 Fingerprint: 77:0d:19:b1:21:fd:00:42:9c:3e:0c:a5:dd:0b:02:8e -# SHA1 Fingerprint: 25:01:90:19:cf:fb:d9:99:1c:b7:68:25:74:8d:94:5f:30:93:95:42 -# SHA256 Fingerprint: af:8b:67:62:a1:e5:28:22:81:61:a9:5d:5c:55:9e:e2:66:27:8f:75:d7:9e:83:01:89:a5:03:50:6a:bd:6b:4c ------BEGIN CERTIFICATE----- -MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6 -MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp -dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX -BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy -MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp -eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg -/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl -wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh -AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2 -PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu -AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR -MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc -HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/ -Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+ -f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO -rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch -6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3 -7CAFYd4= ------END CERTIFICATE----- - # Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. # Subject: CN=GeoTrust Global CA O=GeoTrust Inc. # Label: "GeoTrust Global CA" @@ -1987,34 +1958,6 @@ oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs yZyQ2uypQjyttgI= -----END CERTIFICATE----- -# Issuer: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327 -# Subject: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327 -# Label: "Buypass Class 2 CA 1" -# Serial: 1 -# MD5 Fingerprint: b8:08:9a:f0:03:cc:1b:0d:c8:6c:0b:76:a1:75:64:23 -# SHA1 Fingerprint: a0:a1:ab:90:c9:fc:84:7b:3b:12:61:e8:97:7d:5f:d3:22:61:d3:cc -# SHA256 Fingerprint: 0f:4e:9c:dd:26:4b:02:55:50:d1:70:80:63:40:21:4f:e9:44:34:c9:b0:2f:69:7e:c7:10:fc:5f:ea:fb:5e:38 ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg -Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL -MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD -VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0 -ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX -l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB -HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B -5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3 -WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD -AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP -gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+ -DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu -BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs -h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk -LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho ------END CERTIFICATE----- - # Issuer: O=certSIGN OU=certSIGN ROOT CA # Subject: O=certSIGN OU=certSIGN ROOT CA # Label: "certSIGN ROOT CA" @@ -2976,51 +2919,6 @@ dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 -----END CERTIFICATE----- -# Issuer: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA -# Subject: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA -# Label: "Root CA Generalitat Valenciana" -# Serial: 994436456 -# MD5 Fingerprint: 2c:8c:17:5e:b1:54:ab:93:17:b5:36:5a:db:d1:c6:f2 -# SHA1 Fingerprint: a0:73:e5:c5:bd:43:61:0d:86:4c:21:13:0a:85:58:57:cc:9c:ea:46 -# SHA256 Fingerprint: 8c:4e:df:d0:43:48:f3:22:96:9e:7e:29:a4:cd:4d:ca:00:46:55:06:1c:16:e1:b0:76:42:2e:f3:42:ad:63:0e ------BEGIN CERTIFICATE----- -MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF -UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ -R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN -MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G -A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw -JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+ -WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj -SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl -u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy -A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk -Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7 -MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr -aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC -IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A -cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA -YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA -bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA -bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA -aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA -aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA -ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA -YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA -ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA -LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6 -Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y -eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw -CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G -A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu -Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn -lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt -b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg -9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF -ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC -IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= ------END CERTIFICATE----- - # Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Label: "TWCA Root Certification Authority" @@ -5315,3 +5213,192 @@ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= -----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Label: "LuxTrust Global Root 2" +# Serial: 59914338225734147123941058376788110305822489521 +# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c +# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f +# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 +-----BEGIN CERTIFICATE----- +MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL +BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV +BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUw +MzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B +LjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wmKb3F +ibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTem +hfY7RBi2xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1 +EMShduxq3sVs35a0VkBCwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsn +Xpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4 +zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkmFRseTJIpgp7VkoGSQXAZ +96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niFwpN6cj5m +j5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4g +DEa/a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+ +8kPREd8vZS9kzl8UubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2j +X5t/Lax5Gw5CMZdjpPuKadUiDTSQMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmH +hFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGByuB +KwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0 +Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT ++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQEL +BQADggIBAGoZFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9 +BzZAcg4atmpZ1gDlaCDdLnINH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTO +jFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW7MM3LGVYvlcAGvI1+ut7MV3CwRI9 +loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIuZY+kt9J/Z93I055c +qqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWAVWe+ +2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/ +JEAdemrRTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKre +zrnK+T+Tb/mjuuqlPpmt/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQf +LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+ +x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6 +oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr +-----END CERTIFICATE----- diff --git a/examples/csharp/helloworld-from-cli/global.json b/examples/csharp/helloworld-from-cli/global.json new file mode 100644 index 00000000000..32ff399ef94 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "1.0.0-preview2-003121" + } +} \ No newline at end of file diff --git a/examples/php/composer.json b/examples/php/composer.json index f0b9977252b..f4b177c2713 100644 --- a/examples/php/composer.json +++ b/examples/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-demo", "description": "gRPC example for PHP", "require": { - "grpc/grpc": "v1.1.0" + "grpc/grpc": "^v1.1.0" }, "autoload": { "psr-4": { diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index beb72276d24..909ea5af967 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -917,7 +917,7 @@ Pod::Spec.new do |s| 'test/core/util/debugger_macros.c', 'test/core/util/test_config.{c,h}', 'test/core/util/port.h', - 'test/core/util/port_posix.c', + 'test/core/util/port.c', 'test/core/util/port_server_client.{c,h}' end end diff --git a/grpc.def b/grpc.def index c660d361b1c..30d60b0d06d 100644 --- a/grpc.def +++ b/grpc.def @@ -258,6 +258,7 @@ EXPORTS gpr_ref_non_zero gpr_refn gpr_unref + gpr_ref_is_unique gpr_stats_init gpr_stats_inc gpr_stats_read diff --git a/include/grpc++/impl/channel_argument_option.h b/include/grpc++/impl/channel_argument_option.h new file mode 100644 index 00000000000..057acc2cebf --- /dev/null +++ b/include/grpc++/impl/channel_argument_option.h @@ -0,0 +1,52 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H +#define GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H + +#include +#include + +#include +#include + +namespace grpc { + +std::unique_ptr MakeChannelArgumentOption( + const grpc::string &name, const grpc::string &value); +std::unique_ptr MakeChannelArgumentOption( + const grpc::string &name, int value); + +} // namespace grpc + +#endif // GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index 2ac2f0a1ef4..d707100a522 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -130,6 +131,13 @@ class ServerBuilder { /// Only useful if this is a Synchronous server. ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); + /// Add a channel argument (an escape hatch to tuning core library parameters + /// directly) + template + ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { + return SetOption(MakeChannelArgumentOption(arg, value)); + } + /// Tries to bind \a server to the given \a addr. /// /// It can be invoked multiple times. diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h index 96aec0c2c09..6a8e8a644f9 100644 --- a/include/grpc/impl/codegen/sync.h +++ b/include/grpc/impl/codegen/sync.h @@ -52,6 +52,10 @@ provides no memory barriers. */ +#ifdef __cplusplus +extern "C" { +#endif + /* Platform-specific type declarations of gpr_mu and gpr_cv. */ #include #include @@ -64,4 +68,8 @@ #error Unable to determine platform for sync #endif +#ifdef __cplusplus +} +#endif + #endif /* GRPC_IMPL_CODEGEN_SYNC_H */ diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h index a7bbb38c27e..5cfeecb6017 100644 --- a/include/grpc/support/sync.h +++ b/include/grpc/support/sync.h @@ -164,6 +164,10 @@ GPRAPI void gpr_refn(gpr_refcount *r, int n); zero. . Requires *r initialized. */ GPRAPI int gpr_unref(gpr_refcount *r); +/* Return non-zero iff the reference count of *r is one, and thus is owned + by exactly one object. */ +GPRAPI int gpr_ref_is_unique(gpr_refcount *r); + /* --- Stats counters --- These calls act on the integral type gpr_stats_counter. It requires no diff --git a/package.xml b/package.xml index d82f2e49a81..e16161d7a2e 100644 --- a/package.xml +++ b/package.xml @@ -10,7 +10,7 @@ grpc-packages@google.com yes - 2017-01-13 + 2017-03-01 1.2.0dev @@ -22,8 +22,8 @@ BSD -- PHP Proto3 adoption #8179 -- Various bug fixes +- Added arg info macros #9751 +- Updated codegen to be consistent with protobuf #9492 @@ -1276,8 +1276,8 @@ Update to wrap gRPC C Core version 0.10.0 - 1.1.0dev - 1.1.0dev + 1.1.0RC1 + 1.1.0RC1 beta @@ -1287,7 +1287,39 @@ Update to wrap gRPC C Core version 0.10.0 BSD - PHP Proto3 adoption #8179 -- Various bug fixes +- Various bug fixes + + + + + 1.1.0 + 1.1.0 + + + stable + stable + + 2017-01-31 + BSD + +- PHP Proto3 adoption #8179 +- Various bug fixes + + + + + 1.2.0RC1 + 1.2.0RC1 + + + beta + beta + + 2017-03-01 + BSD + +- Added arg info macros #9751 +- Updated codegen to be consistent with protobuf #9492 diff --git a/requirements.txt b/requirements.txt index bf87de07f89..12969958aee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ coverage>=4.0 cython>=0.23 enum34>=1.0.4 futures>=2.2.0 -protobuf>=3.0.0 +protobuf>=3.2.0 six>=1.10 wheel>=0.29 diff --git a/setup.py b/setup.py index 234252a16ca..d5b843fdace 100644 --- a/setup.py +++ b/setup.py @@ -209,7 +209,7 @@ INSTALL_REQUIRES = ( 'enum34>=1.0.4', # TODO(atash): eventually split the grpcio package into a metapackage # depending on protobuf and the runtime component (independent of protobuf) - 'protobuf>=3.0.0', + 'protobuf>=3.2.0', ) if not PY3: diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index e481aaf811b..2908b639f39 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -102,7 +102,7 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) { vars["filename_base"] = file->filename_without_ext(); vars["message_header_ext"] = file->message_header_ext(); - printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n"); + printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, "// If you make any local change, they will be lost.\n"); printer->Print(vars, "// source: $filename$\n"); @@ -1010,7 +1010,7 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) { vars["message_header_ext"] = file->message_header_ext(); vars["service_header_ext"] = file->service_header_ext(); - printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n"); + printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, "// If you make any local change, they will be lost.\n"); printer->Print(vars, "// source: $filename$\n\n"); diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index 34015c534e1..bf64f84772c 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -76,24 +76,82 @@ typedef enum { WAIT_FOR_READY_TRUE } wait_for_ready_value; -typedef struct method_parameters { +typedef struct { + gpr_refcount refs; gpr_timespec timeout; wait_for_ready_value wait_for_ready; } method_parameters; +static method_parameters *method_parameters_ref( + method_parameters *method_params) { + gpr_ref(&method_params->refs); + return method_params; +} + +static void method_parameters_unref(method_parameters *method_params) { + if (gpr_unref(&method_params->refs)) { + gpr_free(method_params); + } +} + static void *method_parameters_copy(void *value) { - void *new_value = gpr_malloc(sizeof(method_parameters)); - memcpy(new_value, value, sizeof(method_parameters)); - return new_value; + return method_parameters_ref(value); } -static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *p) { - gpr_free(p); +static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *value) { + method_parameters_unref(value); } static const grpc_slice_hash_table_vtable method_parameters_vtable = { method_parameters_free, method_parameters_copy}; +static bool parse_wait_for_ready(grpc_json *field, + wait_for_ready_value *wait_for_ready) { + if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { + return false; + } + *wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE + : WAIT_FOR_READY_FALSE; + return true; +} + +static bool parse_timeout(grpc_json *field, gpr_timespec *timeout) { + if (field->type != GRPC_JSON_STRING) return false; + size_t len = strlen(field->value); + if (field->value[len - 1] != 's') return false; + char *buf = gpr_strdup(field->value); + buf[len - 1] = '\0'; // Remove trailing 's'. + char *decimal_point = strchr(buf, '.'); + if (decimal_point != NULL) { + *decimal_point = '\0'; + timeout->tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1); + if (timeout->tv_nsec == -1) { + gpr_free(buf); + return false; + } + // There should always be exactly 3, 6, or 9 fractional digits. + int multiplier = 1; + switch (strlen(decimal_point + 1)) { + case 9: + break; + case 6: + multiplier *= 1000; + break; + case 3: + multiplier *= 1000000; + break; + default: // Unsupported number of digits. + gpr_free(buf); + return false; + } + timeout->tv_nsec *= multiplier; + } + timeout->tv_sec = gpr_parse_nonnegative_int(buf); + gpr_free(buf); + if (timeout->tv_sec == -1) return false; + return true; +} + static void *method_parameters_create_from_json(const grpc_json *json) { wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET; gpr_timespec timeout = {0, 0, GPR_TIMESPAN}; @@ -101,49 +159,14 @@ static void *method_parameters_create_from_json(const grpc_json *json) { if (field->key == NULL) continue; if (strcmp(field->key, "waitForReady") == 0) { if (wait_for_ready != WAIT_FOR_READY_UNSET) return NULL; // Duplicate. - if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { - return NULL; - } - wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE - : WAIT_FOR_READY_FALSE; + if (!parse_wait_for_ready(field, &wait_for_ready)) return NULL; } else if (strcmp(field->key, "timeout") == 0) { if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL; // Duplicate. - if (field->type != GRPC_JSON_STRING) return NULL; - size_t len = strlen(field->value); - if (field->value[len - 1] != 's') return NULL; - char *buf = gpr_strdup(field->value); - buf[len - 1] = '\0'; // Remove trailing 's'. - char *decimal_point = strchr(buf, '.'); - if (decimal_point != NULL) { - *decimal_point = '\0'; - timeout.tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1); - if (timeout.tv_nsec == -1) { - gpr_free(buf); - return NULL; - } - // There should always be exactly 3, 6, or 9 fractional digits. - int multiplier = 1; - switch (strlen(decimal_point + 1)) { - case 9: - break; - case 6: - multiplier *= 1000; - break; - case 3: - multiplier *= 1000000; - break; - default: // Unsupported number of digits. - gpr_free(buf); - return NULL; - } - timeout.tv_nsec *= multiplier; - } - timeout.tv_sec = gpr_parse_nonnegative_int(buf); - if (timeout.tv_sec == -1) return NULL; - gpr_free(buf); + if (!parse_timeout(field, &timeout)) return NULL; } } method_parameters *value = gpr_malloc(sizeof(method_parameters)); + gpr_ref_init(&value->refs, 1); value->timeout = timeout; value->wait_for_ready = wait_for_ready; return value; @@ -629,7 +652,7 @@ typedef struct client_channel_call_data { grpc_slice path; // Request path. gpr_timespec call_start_time; gpr_timespec deadline; - wait_for_ready_value wait_for_ready_from_service_config; + method_parameters *method_params; grpc_closure read_service_config; grpc_error *cancel_error; @@ -837,10 +860,11 @@ static bool pick_subchannel_locked( initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET; const bool wait_for_ready_set_from_service_config = - calld->wait_for_ready_from_service_config != WAIT_FOR_READY_UNSET; + calld->method_params != NULL && + calld->method_params->wait_for_ready != WAIT_FOR_READY_UNSET; if (!wait_for_ready_set_from_api && wait_for_ready_set_from_service_config) { - if (calld->wait_for_ready_from_service_config == WAIT_FOR_READY_TRUE) { + if (calld->method_params->wait_for_ready == WAIT_FOR_READY_TRUE) { initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; } else { initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; @@ -978,10 +1002,9 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx, add_waiting_locked(calld, op); } -static void cc_start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, - void *arg, - grpc_error *error_ignored) { - GPR_TIMER_BEGIN("cc_start_transport_stream_op_locked", 0); +static void start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error_ignored) { + GPR_TIMER_BEGIN("start_transport_stream_op_locked", 0); grpc_transport_stream_op *op = arg; grpc_call_element *elem = op->handler_private.args[0]; @@ -991,7 +1014,7 @@ static void cc_start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "start_transport_stream_op"); - GPR_TIMER_END("cc_start_transport_stream_op_locked", 0); + GPR_TIMER_END("start_transport_stream_op_locked", 0); } /* The logic here is fairly complicated, due to (a) the fact that we @@ -1031,52 +1054,53 @@ static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_closure_sched( exec_ctx, grpc_closure_init(&op->handler_private.closure, - cc_start_transport_stream_op_locked, op, + start_transport_stream_op_locked, op, grpc_combiner_scheduler(chand->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("cc_start_transport_stream_op", 0); } +// Sets calld->method_params. +// If the method params specify a timeout, populates +// *per_method_deadline and returns true. +static bool set_call_method_params_from_service_config_locked( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + gpr_timespec *per_method_deadline) { + channel_data *chand = elem->channel_data; + call_data *calld = elem->call_data; + if (chand->method_params_table != NULL) { + calld->method_params = grpc_method_config_table_get( + exec_ctx, chand->method_params_table, calld->path); + if (calld->method_params != NULL) { + method_parameters_ref(calld->method_params); + if (gpr_time_cmp(calld->method_params->timeout, + gpr_time_0(GPR_TIMESPAN)) != 0) { + *per_method_deadline = + gpr_time_add(calld->call_start_time, calld->method_params->timeout); + return true; + } + } + } + return false; +} + // Gets data from the service config. Invoked when the resolver returns // its initial result. static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_call_element *elem = arg; - channel_data *chand = elem->channel_data; call_data *calld = elem->call_data; // If this is an error, there's no point in looking at the service config. if (error == GRPC_ERROR_NONE) { - // Get the method config table from channel data. - grpc_slice_hash_table *method_params_table = NULL; - if (chand->method_params_table != NULL) { - method_params_table = - grpc_slice_hash_table_ref(chand->method_params_table); - } - // If the method config table was present, use it. - if (method_params_table != NULL) { - const method_parameters *method_params = grpc_method_config_table_get( - exec_ctx, method_params_table, calld->path); - if (method_params != NULL) { - const bool have_method_timeout = - gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_TIMESPAN)) != 0; - if (have_method_timeout || - method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { - if (have_method_timeout) { - const gpr_timespec per_method_deadline = - gpr_time_add(calld->call_start_time, method_params->timeout); - if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) { - calld->deadline = per_method_deadline; - // Reset deadline timer. - grpc_deadline_state_reset(exec_ctx, elem, calld->deadline); - } - } - if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { - calld->wait_for_ready_from_service_config = - method_params->wait_for_ready; - } - } + gpr_timespec per_method_deadline; + if (set_call_method_params_from_service_config_locked( + exec_ctx, elem, &per_method_deadline)) { + // If the deadline from the service config is shorter than the one + // from the client API, reset the deadline timer. + if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) { + calld->deadline = per_method_deadline; + grpc_deadline_state_reset(exec_ctx, elem, calld->deadline); } - grpc_slice_hash_table_unref(exec_ctx, method_params_table); } } GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config"); @@ -1091,29 +1115,12 @@ static void initial_read_service_config_locked(grpc_exec_ctx *exec_ctx, // If the resolver has already returned results, then we can access // the service config parameters immediately. Otherwise, we need to // defer that work until the resolver returns an initial result. - // TODO(roth): This code is almost but not quite identical to the code - // in read_service_config() above. It would be nice to find a way to - // combine them, to avoid having to maintain it twice. if (chand->lb_policy != NULL) { // We already have a resolver result, so check for service config. - if (chand->method_params_table != NULL) { - grpc_slice_hash_table *method_params_table = - grpc_slice_hash_table_ref(chand->method_params_table); - method_parameters *method_params = grpc_method_config_table_get( - exec_ctx, method_params_table, calld->path); - if (method_params != NULL) { - if (gpr_time_cmp(method_params->timeout, - gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) { - gpr_timespec per_method_deadline = - gpr_time_add(calld->call_start_time, method_params->timeout); - calld->deadline = gpr_time_min(calld->deadline, per_method_deadline); - } - if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { - calld->wait_for_ready_from_service_config = - method_params->wait_for_ready; - } - } - grpc_slice_hash_table_unref(exec_ctx, method_params_table); + gpr_timespec per_method_deadline; + if (set_call_method_params_from_service_config_locked( + exec_ctx, elem, &per_method_deadline)) { + calld->deadline = gpr_time_min(calld->deadline, per_method_deadline); } } else { // We don't yet have a resolver result, so register a callback to @@ -1144,7 +1151,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, calld->path = grpc_slice_ref_internal(args->path); calld->call_start_time = args->start_time; calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC); - calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET; + calld->method_params = NULL; calld->cancel_error = GRPC_ERROR_NONE; gpr_atm_rel_store(&calld->subchannel_call, 0); calld->connected_subchannel = NULL; @@ -1172,6 +1179,9 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx, call_data *calld = elem->call_data; grpc_deadline_state_destroy(exec_ctx, elem); grpc_slice_unref_internal(exec_ctx, calld->path); + if (calld->method_params != NULL) { + method_parameters_unref(calld->method_params); + } GRPC_ERROR_UNREF(calld->cancel_error); grpc_subchannel_call *call = GET_CALL(calld); if (call != NULL && call != CANCELLED_CALL) { diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c index 6f9df3e386e..28d3b63f99d 100644 --- a/src/core/ext/client_channel/client_channel_plugin.c +++ b/src/core/ext/client_channel/client_channel_plugin.c @@ -64,7 +64,7 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx, } } char *default_authority = grpc_get_default_authority( - grpc_channel_stack_builder_get_target(builder)); + exec_ctx, grpc_channel_stack_builder_get_target(builder)); if (default_authority != NULL) { grpc_arg arg; arg.type = GRPC_ARG_STRING; diff --git a/src/core/ext/client_channel/http_proxy.c b/src/core/ext/client_channel/http_proxy.c index bbe4ff550c6..e280cef101f 100644 --- a/src/core/ext/client_channel/http_proxy.c +++ b/src/core/ext/client_channel/http_proxy.c @@ -46,10 +46,11 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/support/env.h" -static char* grpc_get_http_proxy_server() { +static char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) { char* uri_str = gpr_getenv("http_proxy"); if (uri_str == NULL) return NULL; - grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */); + grpc_uri* uri = + grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */); char* proxy_name = NULL; if (uri == NULL || uri->authority == NULL) { gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var"); @@ -76,9 +77,10 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx, const grpc_channel_args* args, char** name_to_resolve, grpc_channel_args** new_args) { - *name_to_resolve = grpc_get_http_proxy_server(); + *name_to_resolve = grpc_get_http_proxy_server(exec_ctx); if (*name_to_resolve == NULL) return false; - grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */); + grpc_uri* uri = + grpc_uri_parse(exec_ctx, server_uri, false /* suppress_errors */); if (uri == NULL || uri->path[0] == '\0') { gpr_log(GPR_ERROR, "'http_proxy' environment variable set, but cannot " diff --git a/src/core/ext/client_channel/parse_address.c b/src/core/ext/client_channel/parse_address.c index b1d55ad0f5f..8ae15fc72bc 100644 --- a/src/core/ext/client_channel/parse_address.c +++ b/src/core/ext/client_channel/parse_address.c @@ -44,16 +44,18 @@ #include #include #include +#include "src/core/lib/support/string.h" #ifdef GRPC_HAVE_UNIX_SOCKET int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) { struct sockaddr_un *un = (struct sockaddr_un *)resolved_addr->addr; - + const size_t maxlen = sizeof(un->sun_path); + const size_t path_len = strnlen(uri->path, maxlen); + if (path_len == maxlen) return 0; un->sun_family = AF_UNIX; strcpy(un->sun_path, uri->path); - resolved_addr->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; - + resolved_addr->len = sizeof(*un); return 1; } @@ -119,9 +121,30 @@ int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) { memset(in6, 0, sizeof(*in6)); resolved_addr->len = sizeof(*in6); in6->sin6_family = AF_INET6; - if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) { - gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); - goto done; + + /* Handle the RFC6874 syntax for IPv6 zone identifiers. */ + char *host_end = (char *)gpr_memrchr(host, '%', strlen(host)); + if (host_end != NULL) { + GPR_ASSERT(host_end >= host); + char host_without_scope[INET6_ADDRSTRLEN]; + size_t host_without_scope_len = (size_t)(host_end - host); + strncpy(host_without_scope, host, host_without_scope_len); + host_without_scope[host_without_scope_len] = '\0'; + if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { + gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host_without_scope); + goto done; + } + if (gpr_parse_bytes_to_uint32(host_end + 1, + strlen(host) - host_without_scope_len - 1, + &in6->sin6_scope_id) == 0) { + gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); + goto done; + } + } else { + if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) { + gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); + goto done; + } } if (port != NULL) { diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c index f8e8bc9c393..3c5a6fb3fff 100644 --- a/src/core/ext/client_channel/resolver_registry.c +++ b/src/core/ext/client_channel/resolver_registry.c @@ -108,22 +108,23 @@ static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) { return lookup_factory(uri->scheme); } -static grpc_resolver_factory *resolve_factory(const char *target, +static grpc_resolver_factory *resolve_factory(grpc_exec_ctx *exec_ctx, + const char *target, grpc_uri **uri, char **canonical_target) { grpc_resolver_factory *factory = NULL; GPR_ASSERT(uri != NULL); - *uri = grpc_uri_parse(target, 1); + *uri = grpc_uri_parse(exec_ctx, target, 1); factory = lookup_factory_by_uri(*uri); if (factory == NULL) { grpc_uri_destroy(*uri); gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target); - *uri = grpc_uri_parse(*canonical_target, 1); + *uri = grpc_uri_parse(exec_ctx, *canonical_target, 1); factory = lookup_factory_by_uri(*uri); if (factory == NULL) { - grpc_uri_destroy(grpc_uri_parse(target, 0)); - grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0)); + grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0)); + grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0)); gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, *canonical_target); } @@ -138,7 +139,7 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target, grpc_uri *uri = NULL; char *canonical_target = NULL; grpc_resolver_factory *factory = - resolve_factory(target, &uri, &canonical_target); + resolve_factory(exec_ctx, target, &uri, &canonical_target); grpc_resolver *resolver; grpc_resolver_args resolver_args; memset(&resolver_args, 0, sizeof(resolver_args)); @@ -153,21 +154,22 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target, return resolver; } -char *grpc_get_default_authority(const char *target) { +char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target) { grpc_uri *uri = NULL; char *canonical_target = NULL; grpc_resolver_factory *factory = - resolve_factory(target, &uri, &canonical_target); + resolve_factory(exec_ctx, target, &uri, &canonical_target); char *authority = grpc_resolver_factory_get_default_authority(factory, uri); grpc_uri_destroy(uri); gpr_free(canonical_target); return authority; } -char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target) { +char *grpc_resolver_factory_add_default_prefix_if_needed( + grpc_exec_ctx *exec_ctx, const char *target) { grpc_uri *uri = NULL; char *canonical_target = NULL; - resolve_factory(target, &uri, &canonical_target); + resolve_factory(exec_ctx, target, &uri, &canonical_target); grpc_uri_destroy(uri); return canonical_target == NULL ? gpr_strdup(target) : canonical_target; } diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h index e2c189cf0cd..1a3ebee25a8 100644 --- a/src/core/ext/client_channel/resolver_registry.h +++ b/src/core/ext/client_channel/resolver_registry.h @@ -74,10 +74,11 @@ grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name); /** Given a target, return a (freshly allocated with gpr_malloc) string representing the default authority to pass from a client. */ -char *grpc_get_default_authority(const char *target); +char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target); /** Returns a newly allocated string containing \a target, adding the default prefix if needed. */ -char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target); +char *grpc_resolver_factory_add_default_prefix_if_needed( + grpc_exec_ctx *exec_ctx, const char *target); #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */ diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c index cb2d2c821de..5df0a9060d0 100644 --- a/src/core/ext/client_channel/subchannel.c +++ b/src/core/ext/client_channel/subchannel.c @@ -331,7 +331,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, } c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address *addr = gpr_malloc(sizeof(*addr)); - grpc_get_subchannel_address_arg(args->args, addr); + grpc_get_subchannel_address_arg(exec_ctx, args->args, addr); grpc_set_initial_connect_string(&addr, &c->initial_connect_string); grpc_resolved_address *new_address = NULL; grpc_channel_args *new_args = NULL; @@ -787,9 +787,9 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack( return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); } -static void grpc_uri_to_sockaddr(const char *uri_str, +static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str, grpc_resolved_address *addr) { - grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); + grpc_uri *uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */); GPR_ASSERT(uri != NULL); if (strcmp(uri->scheme, "ipv4") == 0) { GPR_ASSERT(parse_ipv4(uri, addr)); @@ -801,12 +801,13 @@ static void grpc_uri_to_sockaddr(const char *uri_str, grpc_uri_destroy(uri); } -void grpc_get_subchannel_address_arg(const grpc_channel_args *args, +void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx, + const grpc_channel_args *args, grpc_resolved_address *addr) { const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args); memset(addr, 0, sizeof(*addr)); if (*addr_uri_str != '\0') { - grpc_uri_to_sockaddr(addr_uri_str, addr); + grpc_uri_to_sockaddr(exec_ctx, addr_uri_str, addr); } } diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h index 26ce9544871..6a70a764676 100644 --- a/src/core/ext/client_channel/subchannel.h +++ b/src/core/ext/client_channel/subchannel.h @@ -175,7 +175,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, const grpc_subchannel_args *args); /// Sets \a addr from \a args. -void grpc_get_subchannel_address_arg(const grpc_channel_args *args, +void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx, + const grpc_channel_args *args, grpc_resolved_address *addr); /// Returns the URI string for the address to connect to. diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/client_channel/uri_parser.c index 7dd7b753cc8..d385db08018 100644 --- a/src/core/ext/client_channel/uri_parser.c +++ b/src/core/ext/client_channel/uri_parser.c @@ -35,13 +35,15 @@ #include -#include #include #include #include #include #include +#include "src/core/lib/slice/percent_encoding.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" /** a size_t default value... maps to all 1's */ @@ -68,11 +70,16 @@ static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section, return NULL; } -/** Returns a copy of \a src[begin, end) */ -static char *copy_component(const char *src, size_t begin, size_t end) { - char *out = gpr_malloc(end - begin + 1); - memcpy(out, src + begin, end - begin); - out[end - begin] = 0; +/** Returns a copy of percent decoded \a src[begin, end) */ +static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src, + size_t begin, size_t end) { + grpc_slice component = + grpc_slice_from_copied_buffer(src + begin, end - begin); + grpc_slice decoded_component = + grpc_permissive_percent_decode_slice(component); + char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII); + grpc_slice_unref_internal(exec_ctx, component); + grpc_slice_unref_internal(exec_ctx, decoded_component); return out; } @@ -175,7 +182,8 @@ static void parse_query_parts(grpc_uri *uri) { } } -grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { +grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text, + int suppress_errors) { grpc_uri *uri; size_t scheme_begin = 0; size_t scheme_end = NOT_SET; @@ -263,11 +271,16 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { } uri = gpr_zalloc(sizeof(*uri)); - uri->scheme = copy_component(uri_text, scheme_begin, scheme_end); - uri->authority = copy_component(uri_text, authority_begin, authority_end); - uri->path = copy_component(uri_text, path_begin, path_end); - uri->query = copy_component(uri_text, query_begin, query_end); - uri->fragment = copy_component(uri_text, fragment_begin, fragment_end); + uri->scheme = + decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end); + uri->authority = decode_and_copy_component(exec_ctx, uri_text, + authority_begin, authority_end); + uri->path = + decode_and_copy_component(exec_ctx, uri_text, path_begin, path_end); + uri->query = + decode_and_copy_component(exec_ctx, uri_text, query_begin, query_end); + uri->fragment = decode_and_copy_component(exec_ctx, uri_text, fragment_begin, + fragment_end); parse_query_parts(uri); return uri; diff --git a/src/core/ext/client_channel/uri_parser.h b/src/core/ext/client_channel/uri_parser.h index 5fe0e8f35e3..efd4302c1c6 100644 --- a/src/core/ext/client_channel/uri_parser.h +++ b/src/core/ext/client_channel/uri_parser.h @@ -35,6 +35,7 @@ #define GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H #include +#include "src/core/lib/iomgr/exec_ctx.h" typedef struct { char *scheme; @@ -51,7 +52,8 @@ typedef struct { } grpc_uri; /** parse a uri, return NULL on failure */ -grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors); +grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text, + int suppress_errors); /** return the part of a query string after the '=' in "?key=xxx&...", or NULL * if key is not present */ diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index aea0fcc33d8..d612591f2eb 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -861,7 +861,7 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI); GPR_ASSERT(arg != NULL); GPR_ASSERT(arg->type == GRPC_ARG_STRING); - grpc_uri *uri = grpc_uri_parse(arg->value.string, true); + grpc_uri *uri = grpc_uri_parse(exec_ctx, arg->value.string, true); GPR_ASSERT(uri->path[0] != '\0'); glb_policy->server_name = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c index fc5e17d8fc9..eae0145ecc7 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.c +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c @@ -226,7 +226,7 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx, grpc_closure *notify) { chttp2_connector *c = (chttp2_connector *)con; grpc_resolved_address addr; - grpc_get_subchannel_address_arg(args->channel_args, &addr); + grpc_get_subchannel_address_arg(exec_ctx, args->channel_args, &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == NULL); c->notify = notify; diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 490a0c560e3..067ac35a5ac 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -72,8 +72,11 @@ static grpc_channel *client_channel_factory_create_channel( grpc_arg arg; arg.type = GRPC_ARG_STRING; arg.key = GRPC_ARG_SERVER_URI; - arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target); - grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + arg.value.string = + grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target); + const char *to_remove[] = {GRPC_ARG_SERVER_URI}; + grpc_channel_args *new_args = + grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); gpr_free(arg.value.string); grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args, GRPC_CLIENT_CHANNEL, NULL); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index d8c18eb1223..f0c241d68ee 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -83,7 +83,7 @@ static grpc_subchannel_args *get_secure_naming_subchannel_args( const char *server_uri_str = server_uri_arg->value.string; GPR_ASSERT(server_uri_str != NULL); grpc_uri *server_uri = - grpc_uri_parse(server_uri_str, true /* supress errors */); + grpc_uri_parse(exec_ctx, server_uri_str, true /* supress errors */); GPR_ASSERT(server_uri != NULL); const char *server_uri_path; server_uri_path = @@ -96,7 +96,7 @@ static grpc_subchannel_args *get_secure_naming_subchannel_args( const char *target_uri_str = grpc_get_subchannel_address_uri_arg(args->args); grpc_uri *target_uri = - grpc_uri_parse(target_uri_str, false /* suppress errors */); + grpc_uri_parse(exec_ctx, target_uri_str, false /* suppress errors */); GPR_ASSERT(target_uri != NULL); if (target_uri->path[0] != '\0') { // "path" may be empty const grpc_slice key = grpc_slice_from_static_string( @@ -181,8 +181,11 @@ static grpc_channel *client_channel_factory_create_channel( grpc_arg arg; arg.type = GRPC_ARG_STRING; arg.key = GRPC_ARG_SERVER_URI; - arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target); - grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + arg.value.string = + grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target); + const char *to_remove[] = {GRPC_ARG_SERVER_URI}; + grpc_channel_args *new_args = + grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); gpr_free(arg.value.string); grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args, GRPC_CLIENT_CHANNEL, NULL); diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 7ed00522c3e..e7f2597f89c 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -381,16 +381,38 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx, s->incoming_window_delta + t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) { - char *msg; - gpr_asprintf(&msg, - "frame of size %d overflows incoming window of %" PRId64, - t->incoming_frame_size, - s->incoming_window_delta + - t->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); - grpc_error *err = GRPC_ERROR_CREATE(msg); - gpr_free(msg); - return err; + if (incoming_frame_size <= + s->incoming_window_delta + + t->settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) { + gpr_log( + GPR_ERROR, + "Incoming frame of size %d exceeds incoming window size of %" PRId64 + ".\n" + "The (un-acked, future) window size would be %" PRId64 + " which is not exceeded.\n" + "This would usually cause a disconnection, but allowing it due to " + "broken HTTP2 implementations in the wild.\n" + "See (for example) https://github.com/netty/netty/issues/6520.", + t->incoming_frame_size, + s->incoming_window_delta + + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE], + s->incoming_window_delta + + t->settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); + } else { + char *msg; + gpr_asprintf(&msg, + "frame of size %d overflows incoming window of %" PRId64, + t->incoming_frame_size, + s->incoming_window_delta + + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); + grpc_error *err = GRPC_ERROR_CREATE(msg); + gpr_free(msg); + return err; + } } GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA("parse", t, s, diff --git a/src/core/lib/http/parser.c b/src/core/lib/http/parser.c index 2f84adc1878..b9c56c103c7 100644 --- a/src/core/lib/http/parser.c +++ b/src/core/lib/http/parser.c @@ -284,9 +284,9 @@ static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte, case GRPC_HTTP_HEADERS: if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) { if (grpc_http1_trace) - gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded", + gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded", GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); - return GRPC_ERROR_NONE; + return GRPC_ERROR_CREATE("HTTP header max line length exceeded"); } parser->cur_line[parser->cur_line_length] = byte; parser->cur_line_length++; diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c index dbe5b139f91..6c4d0157c20 100644 --- a/src/core/lib/iomgr/error.c +++ b/src/core/lib/iomgr/error.c @@ -262,6 +262,8 @@ static grpc_error *copy_error_and_unref(grpc_error *in) { GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED); else out = GRPC_ERROR_CREATE("unknown"); + } else if (gpr_ref_is_unique(&in->refs)) { + return in; } else { out = gpr_malloc(sizeof(*out)); #ifdef GRPC_ERROR_REFCOUNT_DEBUG diff --git a/src/core/lib/iomgr/pollset_uv.c b/src/core/lib/iomgr/pollset_uv.c index a379ddf25f8..af33949c698 100644 --- a/src/core/lib/iomgr/pollset_uv.c +++ b/src/core/lib/iomgr/pollset_uv.c @@ -57,14 +57,28 @@ int grpc_pollset_work_run_loop; gpr_mu grpc_polling_mu; +/* This is used solely to kick the uv loop, by setting a callback to be run + immediately in the next loop iteration. + Note: In the future, if there is a bug that involves missing wakeups in the + future, try adding a uv_async_t to kick the loop differently */ +uv_timer_t dummy_uv_handle; + size_t grpc_pollset_size() { return sizeof(grpc_pollset); } +void dummy_timer_cb(uv_timer_t *handle) {} + void grpc_pollset_global_init(void) { gpr_mu_init(&grpc_polling_mu); + uv_timer_init(uv_default_loop(), &dummy_uv_handle); grpc_pollset_work_run_loop = 1; } -void grpc_pollset_global_shutdown(void) { gpr_mu_destroy(&grpc_polling_mu); } +static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; } + +void grpc_pollset_global_shutdown(void) { + gpr_mu_destroy(&grpc_polling_mu); + uv_close((uv_handle_t *)&dummy_uv_handle, timer_close_cb); +} void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { *mu = &grpc_polling_mu; @@ -72,8 +86,6 @@ void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { pollset->shutting_down = 0; } -static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; } - void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_closure *closure) { GPR_ASSERT(!pollset->shutting_down); @@ -81,6 +93,9 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, if (grpc_pollset_work_run_loop) { // Drain any pending UV callbacks without blocking uv_run(uv_default_loop(), UV_RUN_NOWAIT); + } else { + // kick the loop once + uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0); } grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE); } @@ -130,6 +145,7 @@ grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_error *grpc_pollset_kick(grpc_pollset *pollset, grpc_pollset_worker *specific_worker) { + uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0); return GRPC_ERROR_NONE; } diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c index ffa62cb53c0..9d2732666b2 100644 --- a/src/core/lib/iomgr/sockaddr_utils.c +++ b/src/core/lib/iomgr/sockaddr_utils.c @@ -162,6 +162,7 @@ int grpc_sockaddr_to_string(char **out, char ntop_buf[INET6_ADDRSTRLEN]; const void *ip = NULL; int port; + uint32_t sin6_scope_id = 0; int ret; *out = NULL; @@ -177,10 +178,19 @@ int grpc_sockaddr_to_string(char **out, const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; ip = &addr6->sin6_addr; port = ntohs(addr6->sin6_port); + sin6_scope_id = addr6->sin6_scope_id; } if (ip != NULL && grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != NULL) { - ret = gpr_join_host_port(out, ntop_buf, port); + if (sin6_scope_id != 0) { + char *host_with_scope; + /* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */ + gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id); + ret = gpr_join_host_port(out, host_with_scope, port); + gpr_free(host_with_scope); + } else { + ret = gpr_join_host_port(out, ntop_buf, port); + } } else { ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); } diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 36f878fdd4d..5f286a6723c 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -114,6 +114,8 @@ struct grpc_tcp_server { /* is this server shutting down? */ bool shutdown; + /* have listeners been shutdown? */ + bool shutdown_listeners; /* use SO_REUSEPORT */ bool so_reuseport; /* expand wildcard addresses to a list of all local addresses */ @@ -161,7 +163,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx, grpc_tcp_server **server) { gpr_once_init(&check_init, init); - grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); + grpc_tcp_server *s = gpr_zalloc(sizeof(grpc_tcp_server)); s->so_reuseport = has_so_reuseport; s->resource_quota = grpc_resource_quota_create(NULL); s->expand_wildcard_addrs = false; @@ -422,7 +424,14 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) { grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); return; default: - gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); + gpr_mu_lock(&sp->server->mu); + if (!sp->server->shutdown_listeners) { + gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); + } else { + /* if we have shutdown listeners, accept4 could fail, and we + needn't notify users */ + } + gpr_mu_unlock(&sp->server->mu); goto error; } } @@ -438,11 +447,6 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) { grpc_fd *fdobj = grpc_fd_create(fd, name); - if (read_notifier_pollset == NULL) { - gpr_log(GPR_ERROR, "Read notifier pollset is not set on the fd"); - goto error; - } - grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj); // Create acceptor. @@ -941,6 +945,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { gpr_mu_lock(&s->mu); + s->shutdown_listeners = true; /* shutdown all fd's */ if (s->active_ports) { grpc_tcp_listener *sp; diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 2a1c8d39fae..d1bcd89af1f 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -485,7 +485,11 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, grpc_schedule_on_exec_ctx); grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure); - s->active_ports++; + /* Registered for both read and write callbacks: increment active_ports + * twice to account for this, and delay free-ing of memory until both + * on_read and on_write have fired. */ + s->active_ports += 2; + sp = sp->next; } diff --git a/src/core/lib/support/sync.c b/src/core/lib/support/sync.c index 44b83f8175a..b52f004f743 100644 --- a/src/core/lib/support/sync.c +++ b/src/core/lib/support/sync.c @@ -37,6 +37,8 @@ #include #include +#include + /* Number of mutexes to allocate for events, to avoid lock contention. Should be a prime. */ enum { event_sync_partitions = 31 }; @@ -99,8 +101,12 @@ void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); } void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); } void gpr_ref_non_zero(gpr_refcount *r) { +#ifndef NDEBUG gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1); - GPR_ASSERT(prior > 0); + assert(prior > 0); +#else + gpr_ref(r); +#endif } void gpr_refn(gpr_refcount *r, int n) { @@ -113,6 +119,10 @@ int gpr_unref(gpr_refcount *r) { return prior == 1; } +int gpr_ref_is_unique(gpr_refcount *r) { + return gpr_atm_acq_load(&r->count) == 1; +} + void gpr_stats_init(gpr_stats_counter *c, intptr_t n) { gpr_atm_rel_store(&c->value, n); } diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 2f212686bc7..cf4410f2c0e 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -156,6 +156,7 @@ struct grpc_call { bool receiving_message; bool requested_final_op; bool received_final_op; + bool sent_any_op; /* have we received initial metadata */ bool has_initial_md_been_received; @@ -485,7 +486,7 @@ void grpc_call_destroy(grpc_call *c) { gpr_mu_lock(&c->mu); GPR_ASSERT(!c->destroy_called); c->destroy_called = 1; - cancel = !c->received_final_op; + cancel = c->sent_any_op && !c->received_final_op; gpr_mu_unlock(&c->mu); if (cancel) { cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE, @@ -1685,6 +1686,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, grpc_closure_init(&bctl->finish_batch, finish_batch, bctl, grpc_schedule_on_exec_ctx); stream_op->on_complete = &bctl->finish_batch; + call->sent_any_op = true; gpr_mu_unlock(&call->mu); execute_op(exec_ctx, call, stream_op); diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c index 23410ef8523..3b0d18c7893 100644 --- a/src/core/lib/transport/transport.c +++ b/src/core/lib/transport/transport.c @@ -84,6 +84,39 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, } } +#define STREAM_REF_FROM_SLICE_REF(p) \ + ((grpc_stream_refcount *)(((uint8_t *)p) - \ + offsetof(grpc_stream_refcount, slice_refcount))) + +static void slice_stream_ref(void *p) { +#ifdef GRPC_STREAM_REFCOUNT_DEBUG + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice"); +#else + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p)); +#endif +} + +static void slice_stream_unref(grpc_exec_ctx *exec_ctx, void *p) { +#ifdef GRPC_STREAM_REFCOUNT_DEBUG + grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p), "slice"); +#else + grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p)); +#endif +} + +grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount, + void *buffer, size_t length) { + slice_stream_ref(&refcount->slice_refcount); + return (grpc_slice){.refcount = &refcount->slice_refcount, + .data.refcounted = {.bytes = buffer, .length = length}}; +} + +static const grpc_slice_refcount_vtable stream_ref_slice_vtable = { + .ref = slice_stream_ref, + .unref = slice_stream_unref, + .eq = grpc_slice_default_eq_impl, + .hash = grpc_slice_default_hash_impl}; + #ifdef GRPC_STREAM_REFCOUNT_DEBUG void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, grpc_iomgr_cb_func cb, void *cb_arg, @@ -95,6 +128,8 @@ void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, #endif gpr_ref_init(&refcount->refs, initial_refs); grpc_closure_init(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); + refcount->slice_refcount.vtable = &stream_ref_slice_vtable; + refcount->slice_refcount.sub_refcount = &refcount->slice_refcount; } static void move64(uint64_t *from, uint64_t *to) { diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index dc1f28106b6..af3a90aa1ea 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -64,6 +64,7 @@ typedef struct grpc_stream_refcount { #ifdef GRPC_STREAM_REFCOUNT_DEBUG const char *object_type; #endif + grpc_slice_refcount slice_refcount; } grpc_stream_refcount; #ifdef GRPC_STREAM_REFCOUNT_DEBUG @@ -84,6 +85,11 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount); grpc_stream_ref_init(rc, ir, cb, cb_arg) #endif +/* Wrap a buffer that is owned by some stream object into a slice that shares + the same refcount */ +grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount, + void *buffer, size_t length); + typedef struct { uint64_t framing_bytes; uint64_t data_bytes; diff --git a/src/core/lib/tsi/test_creds/BUILD b/src/core/lib/tsi/test_creds/BUILD new file mode 100644 index 00000000000..5cf04caf170 --- /dev/null +++ b/src/core/lib/tsi/test_creds/BUILD @@ -0,0 +1,36 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +licenses(["notice"]) # 3-clause BSD + +exports_files([ + "ca.pem", + "server1.key", + "server1.pem", +]) diff --git a/src/cpp/server/channel_argument_option.cc b/src/cpp/server/channel_argument_option.cc new file mode 100644 index 00000000000..723f968ff86 --- /dev/null +++ b/src/cpp/server/channel_argument_option.cc @@ -0,0 +1,78 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +namespace grpc { + +std::unique_ptr MakeChannelArgumentOption( + const grpc::string &name, const grpc::string &value) { + class StringOption final : public ServerBuilderOption { + public: + StringOption(const grpc::string &name, const grpc::string &value) + : name_(name), value_(value) {} + + virtual void UpdateArguments(ChannelArguments *args) override { + args->SetString(name_, value_); + } + virtual void UpdatePlugins( + std::vector> *plugins) override {} + + private: + const grpc::string name_; + const grpc::string value_; + }; + return std::unique_ptr(new StringOption(name, value)); +} + +std::unique_ptr MakeChannelArgumentOption( + const grpc::string &name, int value) { + class IntOption final : public ServerBuilderOption { + public: + IntOption(const grpc::string &name, int value) + : name_(name), value_(value) {} + + virtual void UpdateArguments(ChannelArguments *args) override { + args->SetInt(name_, value_); + } + virtual void UpdatePlugins( + std::vector> *plugins) override {} + + private: + const grpc::string name_; + const int value_; + }; + return std::unique_ptr(new IntOption(name, value)); +} + +} // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index 46def70e8a3..bc98ce79a77 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -63,7 +63,9 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { // Decode request. std::vector slices; - request->Dump(&slices); + if (!request->Dump(&slices).ok()) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } uint8_t* request_bytes = nullptr; bool request_bytes_owned = false; size_t request_size = 0; diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 00a90bb184c..4eb4b5a1b21 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -323,9 +323,14 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } } + bool added_port = false; for (auto port = ports_.begin(); port != ports_.end(); port++) { int r = server->AddListeningPort(port->addr, port->creds.get()); - if (!r) return nullptr; + if (!r) { + if (added_port) server->Shutdown(); + return nullptr; + } + added_port = true; if (port->selected_port != nullptr) { *port->selected_port = r; } @@ -333,6 +338,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { auto cqs_data = cqs_.empty() ? nullptr : &cqs_[0]; if (!server->Start(cqs_data, cqs_.size())) { + if (added_port) server->Shutdown(); return nullptr; } diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 9e11a8a9e07..e874892e73c 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -534,7 +534,7 @@ bool Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { void Server::ShutdownInternal(gpr_timespec deadline) { std::unique_lock lock(mu_); - if (started_ && !shutdown_) { + if (!shutdown_) { shutdown_ = true; /// The completion queue to use for server shutdown completion notification diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index db55ed5a6c8..9ef98529e85 100644 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -34,32 +34,26 @@ - - ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - - ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll + + ..\packages\Google.Apis.Core.1.21.0\lib\net45\Google.Apis.Core.dll + - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll + ..\packages\Google.Apis.1.21.0\lib\net45\Google.Apis.dll - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll + ..\packages\Google.Apis.1.21.0\lib\net45\Google.Apis.PlatformServices.dll - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll + ..\packages\Google.Apis.Auth.1.21.0\lib\net45\Google.Apis.Auth.dll - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + ..\packages\Google.Apis.Auth.1.21.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config index 11c6375c638..aecc65e8499 100644 --- a/src/csharp/Grpc.Auth/packages.config +++ b/src/csharp/Grpc.Auth/packages.config @@ -1,10 +1,8 @@  - - - - - - + + + + \ No newline at end of file diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json index 3805f4759e8..170149ace52 100644 --- a/src/csharp/Grpc.Auth/project.json +++ b/src/csharp/Grpc.Auth/project.json @@ -22,7 +22,7 @@ }, "dependencies": { "Grpc.Core": "1.2.0-dev", - "Google.Apis.Auth": "1.16.0" + "Google.Apis.Auth": "1.21.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.Core.Tests/AuthContextTest.cs b/src/csharp/Grpc.Core.Tests/AuthContextTest.cs new file mode 100644 index 00000000000..f5fa469520c --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/AuthContextTest.cs @@ -0,0 +1,86 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using NUnit.Framework; +using Grpc.Core; +using System.Linq; + +namespace Grpc.Core.Tests +{ + public class AuthContextTest + { + [Test] + public void EmptyContext() + { + var context = new AuthContext(null, new Dictionary>()); + Assert.IsFalse(context.IsPeerAuthenticated); + Assert.IsNull(context.PeerIdentityPropertyName); + Assert.AreEqual(0, context.PeerIdentity.Count()); + Assert.AreEqual(0, context.Properties.Count()); + Assert.AreEqual(0, context.FindPropertiesByName("nonexistent").Count()); + } + + [Test] + public void AuthenticatedContext() + { + var property1 = AuthProperty.Create("abc", new byte[] { 68, 69, 70 }); + var context = new AuthContext("some_identity", new Dictionary> + { + {"some_identity", new List {property1}} + }); + Assert.IsTrue(context.IsPeerAuthenticated); + Assert.AreEqual("some_identity", context.PeerIdentityPropertyName); + Assert.AreEqual(1, context.PeerIdentity.Count()); + } + + [Test] + public void FindPropertiesByName() + { + var property1 = AuthProperty.Create("abc", new byte[] {68, 69, 70}); + var property2 = AuthProperty.Create("abc", new byte[] {71, 72, 73 }); + var property3 = AuthProperty.Create("abc", new byte[] {}); + var context = new AuthContext(null, new Dictionary> + { + {"existent", new List {property1, property2}}, + {"foobar", new List {property3}}, + }); + Assert.AreEqual(3, context.Properties.Count()); + Assert.AreEqual(0, context.FindPropertiesByName("nonexistent").Count()); + + var existentProperties = new List(context.FindPropertiesByName("existent")); + Assert.AreEqual(2, existentProperties.Count); + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/AuthPropertyTest.cs b/src/csharp/Grpc.Core.Tests/AuthPropertyTest.cs new file mode 100644 index 00000000000..745191b80db --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/AuthPropertyTest.cs @@ -0,0 +1,82 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using NUnit.Framework; + +namespace Grpc.Core.Tests +{ + public class AuthPropertyTest + { + [Test] + public void Create_NameIsNotNull() + { + Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.Create(null, new byte[0])); + Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.CreateUnsafe(null, new byte[0])); + } + + [Test] + public void Create_ValueIsNotNull() + { + Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.Create("abc", null)); + Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.CreateUnsafe("abc", null)); + } + + [Test] + public void Create() + { + var valueBytes = new byte[] { 68, 69, 70 }; + var authProperty = AuthProperty.Create("abc", valueBytes); + + Assert.AreEqual("abc", authProperty.Name); + Assert.AreNotSame(valueBytes, authProperty.ValueBytesUnsafe); + CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytes); + CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytesUnsafe); + Assert.AreEqual("DEF", authProperty.Value); + } + + [Test] + public void CreateUnsafe() + { + var valueBytes = new byte[] { 68, 69, 70 }; + var authProperty = AuthProperty.CreateUnsafe("abc", valueBytes); + + Assert.AreEqual("abc", authProperty.Name); + Assert.AreSame(valueBytes, authProperty.ValueBytesUnsafe); + Assert.AreNotSame(valueBytes, authProperty.ValueBytes); + CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytes); + CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytesUnsafe); + Assert.AreEqual("DEF", authProperty.Value); + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index 6bf9756962e..3a99107c422 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -375,6 +375,18 @@ namespace Grpc.Core.Tests Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); } + [Test] + public void ServerCallContext_AuthContextNotPopulated() + { + helper.UnaryHandler = new UnaryServerMethod(async (request, context) => + { + Assert.IsFalse(context.AuthContext.IsPeerAuthenticated); + Assert.AreEqual(0, context.AuthContext.Properties.Count()); + return "PASS"; + }); + Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); + } + [Test] public async Task Channel_WaitForStateChangedAsync() { diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 646effe21a7..a1a2e4eebd1 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -27,17 +27,17 @@ - - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - - - ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + + ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll + + + ..\packages\NUnitLite.3.6.0\lib\net45\nunitlite.dll @@ -64,7 +64,6 @@ - @@ -81,6 +80,8 @@ + + diff --git a/src/csharp/Grpc.Core.Tests/TestResult.xml b/src/csharp/Grpc.Core.Tests/TestResult.xml deleted file mode 100644 index 13da80739ce..00000000000 --- a/src/csharp/Grpc.Core.Tests/TestResult.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config index 4750735fadb..994a2787629 100644 --- a/src/csharp/Grpc.Core.Tests/packages.config +++ b/src/csharp/Grpc.Core.Tests/packages.config @@ -1,9 +1,8 @@  - - - - + + + diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json index 045207a413d..14e5ed51adb 100644 --- a/src/csharp/Grpc.Core.Tests/project.json +++ b/src/csharp/Grpc.Core.Tests/project.json @@ -45,10 +45,10 @@ "Grpc.Core": { "target": "project" }, - "Newtonsoft.Json": "8.0.3", - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*", - "NUnit.ConsoleRunner": "3.2.0", + "Newtonsoft.Json": "9.0.1", + "NUnit": "3.6.0", + "NUnitLite": "3.6.0", + "NUnit.ConsoleRunner": "3.6.0", "OpenCover": "4.6.519", "ReportGenerator": "2.4.4.0" }, diff --git a/src/csharp/Grpc.Core/AuthContext.cs b/src/csharp/Grpc.Core/AuthContext.cs new file mode 100644 index 00000000000..340b2201c79 --- /dev/null +++ b/src/csharp/Grpc.Core/AuthContext.cs @@ -0,0 +1,128 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core +{ + /// + /// Authentication context for a call. + /// AuthContext is the only reliable source of truth when it comes to authenticating calls. + /// Using any other call/context properties for authentication purposes is wrong and inherently unsafe. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public class AuthContext + { + string peerIdentityPropertyName; + Dictionary> properties; + + /// + /// Initializes a new instance of the class. + /// + /// Peer identity property name. + /// Multimap of auth properties by name. + internal AuthContext(string peerIdentityPropertyName, Dictionary> properties) + { + this.peerIdentityPropertyName = peerIdentityPropertyName; + this.properties = GrpcPreconditions.CheckNotNull(properties); + } + + /// + /// Returns true if the peer is authenticated. + /// + public bool IsPeerAuthenticated + { + get + { + return peerIdentityPropertyName != null; + } + } + + /// + /// Gets the name of the property that indicates the peer identity. Returns null + /// if the peer is not authenticated. + /// + public string PeerIdentityPropertyName + { + get + { + return peerIdentityPropertyName; + } + } + + /// + /// Gets properties that represent the peer identity (there can be more than one). Returns an empty collection + /// if the peer is not authenticated. + /// + public IEnumerable PeerIdentity + { + get + { + if (peerIdentityPropertyName == null) + { + return Enumerable.Empty(); + } + return properties[peerIdentityPropertyName]; + } + } + + /// + /// Gets the auth properties of this context. + /// + public IEnumerable Properties + { + get + { + return properties.Values.SelectMany(v => v); + } + } + + /// + /// Returns the auth properties with given name (there can be more than one). + /// If no properties of given name exist, an empty collection will be returned. + /// + public IEnumerable FindPropertiesByName(string propertyName) + { + List result; + if (!properties.TryGetValue(propertyName, out result)) + { + return Enumerable.Empty(); + } + return result; + } + } +} diff --git a/src/csharp/Grpc.Core/AuthProperty.cs b/src/csharp/Grpc.Core/AuthProperty.cs new file mode 100644 index 00000000000..c7a132b09eb --- /dev/null +++ b/src/csharp/Grpc.Core/AuthProperty.cs @@ -0,0 +1,126 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core +{ + /// + /// A property of an . + /// Note: experimental API that can change or be removed without any prior notice. + /// + public class AuthProperty + { + string name; + byte[] valueBytes; + Lazy value; + + private AuthProperty(string name, byte[] valueBytes) + { + this.name = GrpcPreconditions.CheckNotNull(name); + this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes); + this.value = new Lazy(() => MarshalUtils.GetStringUTF8(this.valueBytes)); + } + + /// + /// Gets the name of the property. + /// + public string Name + { + get + { + return name; + } + } + + /// + /// Gets the string value of the property. + /// + public string Value + { + get + { + return value.Value; + } + } + + /// + /// Gets the binary value of the property. + /// + public byte[] ValueBytes + { + get + { + var valueCopy = new byte[valueBytes.Length]; + Buffer.BlockCopy(valueBytes, 0, valueCopy, 0, valueBytes.Length); + return valueCopy; + } + } + + /// + /// Creates an instance of AuthProperty. + /// + /// the name + /// the binary value of the property + public static AuthProperty Create(string name, byte[] valueBytes) + { + GrpcPreconditions.CheckNotNull(valueBytes); + var valueCopy = new byte[valueBytes.Length]; + Buffer.BlockCopy(valueBytes, 0, valueCopy, 0, valueBytes.Length); + return new AuthProperty(name, valueCopy); + } + + /// + /// Gets the binary value of the property (without making a defensive copy). + /// + internal byte[] ValueBytesUnsafe + { + get + { + return valueBytes; + } + } + + /// + /// Creates and instance of AuthProperty without making a defensive copy of valueBytes. + /// + internal static AuthProperty CreateUnsafe(string name, byte[] valueBytes) + { + return new AuthProperty(name, valueBytes); + } + } +} diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 23e1ddcf7f7..d6d8dfac224 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -131,6 +131,10 @@ + + + + diff --git a/src/csharp/Grpc.Core/Internal/AuthContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/AuthContextSafeHandle.cs new file mode 100644 index 00000000000..59e33a0fdf1 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/AuthContextSafeHandle.cs @@ -0,0 +1,119 @@ +#region Copyright notice and license + +// Copyright 2017, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using Grpc.Core; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// grpc_auth_context + /// + internal class AuthContextSafeHandle : SafeHandleZeroIsInvalid + { + static readonly NativeMethods Native = NativeMethods.Get(); + + private AuthContextSafeHandle() + { + } + + /// + /// Copies contents of the native auth context into a new AuthContext instance. + /// + public AuthContext ToAuthContext() + { + if (IsInvalid) + { + return new AuthContext(null, new Dictionary>()); + } + + var peerIdentityPropertyName = Marshal.PtrToStringAnsi(Native.grpcsharp_auth_context_peer_identity_property_name(this)); + + var propertiesDict = new Dictionary>(); + + var it = Native.grpcsharp_auth_context_property_iterator(this); + IntPtr authPropertyPtr = IntPtr.Zero; + while ((authPropertyPtr = Native.grpcsharp_auth_property_iterator_next(ref it)) != IntPtr.Zero) + { + var authProperty = PtrToAuthProperty(authPropertyPtr); + + if (!propertiesDict.ContainsKey(authProperty.Name)) + { + propertiesDict[authProperty.Name] = new List(); + } + propertiesDict[authProperty.Name].Add(authProperty); + } + + return new AuthContext(peerIdentityPropertyName, propertiesDict); + } + + protected override bool ReleaseHandle() + { + Native.grpcsharp_auth_context_release(handle); + return true; + } + + private AuthProperty PtrToAuthProperty(IntPtr authPropertyPtr) + { + var nativeAuthProperty = (NativeAuthProperty) Marshal.PtrToStructure(authPropertyPtr, typeof(NativeAuthProperty)); + var name = Marshal.PtrToStringAnsi(nativeAuthProperty.Name); + var valueBytes = new byte[(int) nativeAuthProperty.ValueLength]; + Marshal.Copy(nativeAuthProperty.Value, valueBytes, 0, (int)nativeAuthProperty.ValueLength); + return AuthProperty.CreateUnsafe(name, valueBytes); + } + + /// + /// grpc_auth_property + /// + internal struct NativeAuthProperty + { + public IntPtr Name; + public IntPtr Value; + public UIntPtr ValueLength; + } + + /// + /// grpc_auth_property_iterator + /// + internal struct NativeAuthPropertyIterator + { + public IntPtr AuthContext; + public UIntPtr Index; + public IntPtr Name; + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index efae149f098..6dee6d8c352 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -43,7 +43,6 @@ namespace Grpc.Core.Internal /// internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid { - static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; static readonly NativeMethods Native = NativeMethods.Get(); private BatchContextSafeHandle() @@ -75,7 +74,7 @@ namespace Grpc.Core.Internal { UIntPtr detailsLength; IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength); - string details = PtrToStringUtf8(detailsPtr, (int) detailsLength.ToUInt32()); + string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int) detailsLength.ToUInt32()); var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); @@ -108,12 +107,5 @@ namespace Grpc.Core.Internal Native.grpcsharp_batch_context_destroy(handle); return true; } - - string PtrToStringUtf8(IntPtr ptr, int len) - { - var bytes = new byte[len]; - Marshal.Copy(ptr, bytes, 0, len); - return EncodingUTF8.GetString(bytes); - } } } diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 710ca480e88..3c368fbc6cd 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -45,7 +45,6 @@ namespace Grpc.Core.Internal internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall { public static readonly CallSafeHandle NullInstance = new CallSafeHandle(); - static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; static readonly NativeMethods Native = NativeMethods.Get(); const uint GRPC_WRITE_BUFFER_HINT = 1; @@ -140,7 +139,7 @@ namespace Grpc.Core.Internal var ctx = BatchContextSafeHandle.Create(); var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero; completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); - var statusDetailBytes = EncodingUTF8.GetBytes(status.Detail); + var statusDetailBytes = MarshalUtils.GetBytesUTF8(status.Detail); Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata, optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); } @@ -204,6 +203,11 @@ namespace Grpc.Core.Internal } } + public AuthContextSafeHandle GetAuthContext() + { + return Native.grpcsharp_call_auth_context(this); + } + protected override bool ReleaseHandle() { Native.grpcsharp_call_destroy(handle); diff --git a/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs similarity index 52% rename from src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs rename to src/csharp/Grpc.Core/Internal/MarshalUtils.cs index 1a9e441611d..897e2f70bb4 100644 --- a/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -32,46 +32,59 @@ #endregion using System; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; -using Grpc.Core.Internal; -using Grpc.Core.Utils; -using NUnit.Framework; +using System.Runtime.InteropServices; +using System.Text; -namespace Grpc.Core.Tests +namespace Grpc.Core.Internal { /// - /// Tests if the version of nunit-console used is sufficient to run async tests. + /// Useful methods for native/managed marshalling. /// - public class NUnitVersionTest + internal static class MarshalUtils { - private int testRunCount = 0; + static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; + static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII; - [TestFixtureTearDown] - public void Cleanup() + /// + /// Converts IntPtr pointing to a UTF-8 encoded byte array to string. + /// + public static string PtrToStringUTF8(IntPtr ptr, int len) { - if (testRunCount != 2) - { - Console.Error.WriteLine("You are using and old version of NUnit that doesn't support async tests and skips them instead. " + - "This test has failed to indicate that."); - Console.Error.Flush(); - throw new Exception("NUnitVersionTest has failed."); - } + var bytes = new byte[len]; + Marshal.Copy(ptr, bytes, 0, len); + return EncodingUTF8.GetString(bytes); } - [Test] - public void NUnitVersionTest1() + /// + /// Returns byte array containing UTF-8 encoding of given string. + /// + public static byte[] GetBytesUTF8(string str) { - testRunCount++; + return EncodingUTF8.GetBytes(str); } - // Old version of NUnit will skip this test - [Test] - public async Task NUnitVersionTest2() + /// + /// Get string from a UTF8 encoded byte array. + /// + public static string GetStringUTF8(byte[] bytes) { - testRunCount++; - await Task.Delay(10); + return EncodingUTF8.GetString(bytes); + } + + /// + /// Returns byte array containing ASCII encoding of given string. + /// + public static byte[] GetBytesASCII(string str) + { + return EncodingASCII.GetBytes(str); + } + + /// + /// Get string from an ASCII encoded byte array. + /// + public static string GetStringASCII(byte[] bytes) + { + return EncodingASCII.GetString(bytes); } } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs index aff9550e8d2..dd65f052172 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs @@ -148,6 +148,12 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate grpcsharp_server_shutdown_and_notify_callback; public readonly Delegates.grpcsharp_server_destroy_delegate grpcsharp_server_destroy; + public readonly Delegates.grpcsharp_call_auth_context_delegate grpcsharp_call_auth_context; + public readonly Delegates.grpcsharp_auth_context_peer_identity_property_name_delegate grpcsharp_auth_context_peer_identity_property_name; + public readonly Delegates.grpcsharp_auth_context_property_iterator_delegate grpcsharp_auth_context_property_iterator; + public readonly Delegates.grpcsharp_auth_property_iterator_next_delegate grpcsharp_auth_property_iterator_next; + public readonly Delegates.grpcsharp_auth_context_release_delegate grpcsharp_auth_context_release; + public readonly Delegates.gprsharp_now_delegate gprsharp_now; public readonly Delegates.gprsharp_inf_future_delegate gprsharp_inf_future; public readonly Delegates.gprsharp_inf_past_delegate gprsharp_inf_past; @@ -256,6 +262,12 @@ namespace Grpc.Core.Internal this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate(library); this.grpcsharp_server_destroy = GetMethodDelegate(library); + this.grpcsharp_call_auth_context = GetMethodDelegate(library); + this.grpcsharp_auth_context_peer_identity_property_name = GetMethodDelegate(library); + this.grpcsharp_auth_context_property_iterator = GetMethodDelegate(library); + this.grpcsharp_auth_property_iterator_next = GetMethodDelegate(library); + this.grpcsharp_auth_context_release = GetMethodDelegate(library); + this.gprsharp_now = GetMethodDelegate(library); this.gprsharp_inf_future = GetMethodDelegate(library); this.gprsharp_inf_past = GetMethodDelegate(library); @@ -404,6 +416,12 @@ namespace Grpc.Core.Internal public delegate void grpcsharp_server_shutdown_and_notify_callback_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); public delegate void grpcsharp_server_destroy_delegate(IntPtr server); + public delegate AuthContextSafeHandle grpcsharp_call_auth_context_delegate(CallSafeHandle call); + public delegate IntPtr grpcsharp_auth_context_peer_identity_property_name_delegate(AuthContextSafeHandle authContext); // returns const char* + public delegate AuthContextSafeHandle.NativeAuthPropertyIterator grpcsharp_auth_context_property_iterator_delegate(AuthContextSafeHandle authContext); + public delegate IntPtr grpcsharp_auth_property_iterator_next_delegate(ref AuthContextSafeHandle.NativeAuthPropertyIterator iterator); // returns const auth_property* + public delegate void grpcsharp_auth_context_release_delegate(IntPtr authContext); + public delegate Timespec gprsharp_now_delegate(ClockType clockType); public delegate Timespec gprsharp_inf_future_delegate(ClockType clockType); public delegate Timespec gprsharp_inf_past_delegate(ClockType clockType); diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 6fc715d6ee1..6e195b49ccd 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -32,12 +32,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.Specialized; -using System.Globalization; -using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; +using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core @@ -242,7 +240,6 @@ namespace Grpc.Core /// public class Entry { - private static readonly Encoding Encoding = Encoding.ASCII; private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$"); readonly string key; @@ -306,7 +303,7 @@ namespace Grpc.Core { if (valueBytes == null) { - return Encoding.GetBytes(value); + return MarshalUtils.GetBytesASCII(value); } // defensive copy to guarantee immutability @@ -324,7 +321,7 @@ namespace Grpc.Core get { GrpcPreconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry"); - return value ?? Encoding.GetString(valueBytes); + return value ?? MarshalUtils.GetStringASCII(valueBytes); } } @@ -358,7 +355,7 @@ namespace Grpc.Core /// internal byte[] GetSerializedValueUnsafe() { - return valueBytes ?? Encoding.GetBytes(value); + return valueBytes ?? MarshalUtils.GetBytesASCII(value); } /// @@ -371,7 +368,7 @@ namespace Grpc.Core { return new Entry(key, null, valueBytes); } - return new Entry(key, Encoding.GetString(valueBytes), null); + return new Entry(key, MarshalUtils.GetStringASCII(valueBytes), null); } private static string NormalizeKey(string key) diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 8f28fbc0453..c8950b76779 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -32,7 +32,6 @@ #endregion using System; -using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -56,6 +55,7 @@ namespace Grpc.Core private Status status = Status.DefaultSuccess; private Func writeHeadersFunc; private IHasWriteOptions writeOptionsHolder; + private Lazy authContext; internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, Func writeHeadersFunc, IHasWriteOptions writeOptionsHolder) @@ -68,6 +68,7 @@ namespace Grpc.Core this.cancellationToken = cancellationToken; this.writeHeadersFunc = writeHeadersFunc; this.writeOptionsHolder = writeOptionsHolder; + this.authContext = new Lazy(GetAuthContextEager); } /// @@ -187,6 +188,26 @@ namespace Grpc.Core writeOptionsHolder.WriteOptions = value; } } + + /// + /// Gets the AuthContext associated with this call. + /// Note: Access to AuthContext is an experimental API that can change without any prior notice. + /// + public AuthContext AuthContext + { + get + { + return authContext.Value; + } + } + + private AuthContext GetAuthContextEager() + { + using (var authContextNative = callHandle.GetAuthContext()) + { + return authContextNative.ToAuthContext(); + } + } } /// diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index d22fe878259..c96243b1c70 100644 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -27,17 +27,17 @@ + + ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll + ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll - ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + ..\packages\NUnitLite.3.6.0\lib\net45\nunitlite.dll - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll - - - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config index 0fed4dbd415..8a7f7a0652a 100644 --- a/src/csharp/Grpc.Examples.Tests/packages.config +++ b/src/csharp/Grpc.Examples.Tests/packages.config @@ -1,7 +1,7 @@  - - - + + + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json index e509621a293..4ffcaf57fd9 100644 --- a/src/csharp/Grpc.Examples.Tests/project.json +++ b/src/csharp/Grpc.Examples.Tests/project.json @@ -45,8 +45,8 @@ "Grpc.Examples": { "target": "project" }, - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 44acb6c2e3a..fc927543f73 100644 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 10.0.0 - 2.0 {7DC1433E-3225-42C7-B7EA-546D56E27A4B} Library Grpc.Examples @@ -28,17 +26,17 @@ 4 - - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - - - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll + + + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll + diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config index c7db26bd64b..79a898081ed 100644 --- a/src/csharp/Grpc.Examples/packages.config +++ b/src/csharp/Grpc.Examples/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json index 21a730cb229..3ee0a713569 100644 --- a/src/csharp/Grpc.Examples/project.json +++ b/src/csharp/Grpc.Examples/project.json @@ -6,15 +6,10 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0" + "Google.Protobuf": "3.2.0" }, "frameworks": { - "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } - }, + "net45": {}, "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index b82f9768612..71f0ee19b86 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -35,14 +35,14 @@ + + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll + - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll + ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll - ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll - - - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + ..\packages\NUnitLite.3.6.0\lib\net45\nunitlite.dll diff --git a/src/csharp/Grpc.HealthCheck.Tests/packages.config b/src/csharp/Grpc.HealthCheck.Tests/packages.config index e796d6b1358..48c94bc4a30 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/packages.config +++ b/src/csharp/Grpc.HealthCheck.Tests/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json index 654454d1cb7..2814cbfe466 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/project.json +++ b/src/csharp/Grpc.HealthCheck.Tests/project.json @@ -45,8 +45,8 @@ "Grpc.HealthCheck": { "target": "project" }, - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 63aa18584d8..171525b7086 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -36,12 +36,12 @@ - - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll + diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config index 5ab40b7a8ce..eec292b306d 100644 --- a/src/csharp/Grpc.HealthCheck/packages.config +++ b/src/csharp/Grpc.HealthCheck/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json index 5d3b2f554b1..9e9d245caec 100644 --- a/src/csharp/Grpc.HealthCheck/project.json +++ b/src/csharp/Grpc.HealthCheck/project.json @@ -22,15 +22,10 @@ }, "dependencies": { "Grpc.Core": "1.2.0-dev", - "Google.Protobuf": "3.0.0" + "Google.Protobuf": "3.2.0" }, "frameworks": { - "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } - }, + "net45": {}, "netstandard1.5": { "dependencies": { "NETStandard.Library": "1.6.0" diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 6bb5f33966e..a793f3f6df8 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -34,33 +34,6 @@ - - ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - - ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - - - ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll - - - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll - - - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll - - - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll - - - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - @@ -82,6 +55,5 @@ - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config deleted file mode 100644 index 11c6375c638..00000000000 --- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config deleted file mode 100644 index 79ece06bef6..00000000000 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index 081dc24fbf1..80d36363f71 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -34,33 +34,6 @@ - - ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - - ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - - - ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll - - - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll - - - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll - - - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll - - - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - @@ -82,6 +55,5 @@ - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config deleted file mode 100644 index 11c6375c638..00000000000 --- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config b/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config deleted file mode 100644 index 79ece06bef6..00000000000 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index 3f4862d5671..6c0176fb43f 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -30,63 +30,66 @@ namespace Grpc.Testing { "cnBjLnRlc3RpbmcuQ2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiAB", "KAsyGy5ncnBjLnRlc3RpbmcuUG9pc3NvblBhcmFtc0gAQgYKBGxvYWQiQwoO", "U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy", - "X2hvc3Rfb3ZlcnJpZGUYAiABKAki8AMKDENsaWVudENvbmZpZxIWCg5zZXJ2", - "ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdycGMu", - "dGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEoCzIc", - "LmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGluZ19y", - "cGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgFIAEo", - "BRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlwZRgI", - "IAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1zGAog", - "ASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9jb25m", - "aWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBoaXN0", - "b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbVBh", - "cmFtcxIRCgljb3JlX2xpc3QYDSADKAUSEgoKY29yZV9saW1pdBgOIAEoBRIY", - "ChBvdGhlcl9jbGllbnRfYXBpGA8gASgJIjgKDENsaWVudFN0YXR1cxIoCgVz", - "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr", - "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy", - "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS", - "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSK0AgoMU2VydmVyQ29u", - "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl", - "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n", - "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy", - "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk", - "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK", - "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhwK", - "E3Jlc291cmNlX3F1b3RhX3NpemUY6QcgASgFImgKClNlcnZlckFyZ3MSKwoF", - "c2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVyQ29uZmlnSAASIgoE", - "bWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSJV", - "CgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rpbmcu", - "U2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3JlcxgDIAEoBSINCgtD", - "b3JlUmVxdWVzdCIdCgxDb3JlUmVzcG9uc2USDQoFY29yZXMYASABKAUiBgoE", - "Vm9pZCL9AQoIU2NlbmFyaW8SDAoEbmFtZRgBIAEoCRIxCg1jbGllbnRfY29u", - "ZmlnGAIgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENvbmZpZxITCgtudW1f", - "Y2xpZW50cxgDIAEoBRIxCg1zZXJ2ZXJfY29uZmlnGAQgASgLMhouZ3JwYy50", - "ZXN0aW5nLlNlcnZlckNvbmZpZxITCgtudW1fc2VydmVycxgFIAEoBRIWCg53", - "YXJtdXBfc2Vjb25kcxgGIAEoBRIZChFiZW5jaG1hcmtfc2Vjb25kcxgHIAEo", - "BRIgChhzcGF3bl9sb2NhbF93b3JrZXJfY291bnQYCCABKAUiNgoJU2NlbmFy", - "aW9zEikKCXNjZW5hcmlvcxgBIAMoCzIWLmdycGMudGVzdGluZy5TY2VuYXJp", - "byL4AgoVU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EgsKA3FwcxgBIAEoARIbChNx", - "cHNfcGVyX3NlcnZlcl9jb3JlGAIgASgBEhoKEnNlcnZlcl9zeXN0ZW1fdGlt", - "ZRgDIAEoARIYChBzZXJ2ZXJfdXNlcl90aW1lGAQgASgBEhoKEmNsaWVudF9z", - "eXN0ZW1fdGltZRgFIAEoARIYChBjbGllbnRfdXNlcl90aW1lGAYgASgBEhIK", - "CmxhdGVuY3lfNTAYByABKAESEgoKbGF0ZW5jeV85MBgIIAEoARISCgpsYXRl", - "bmN5Xzk1GAkgASgBEhIKCmxhdGVuY3lfOTkYCiABKAESEwoLbGF0ZW5jeV85", - "OTkYCyABKAESGAoQc2VydmVyX2NwdV91c2FnZRgMIAEoARImCh5zdWNjZXNz", - "ZnVsX3JlcXVlc3RzX3Blcl9zZWNvbmQYDSABKAESIgoaZmFpbGVkX3JlcXVl", - "c3RzX3Blcl9zZWNvbmQYDiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNj", - "ZW5hcmlvGAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVu", - "Y2llcxgCIAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNs", - "aWVudF9zdGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIv", - "CgxzZXJ2ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3Rh", - "dHMSFAoMc2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5n", - "cnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9z", - "dWNjZXNzGAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVl", - "c3RfcmVzdWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0", - "Q291bnQqQQoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5D", - "X0NMSUVOVBABEhAKDE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoL", - "U1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5F", - "UklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhADKiMKB1JwY1R5cGUSCQoF", - "VU5BUlkQABINCglTVFJFQU1JTkcQAWIGcHJvdG8z")); + "X2hvc3Rfb3ZlcnJpZGUYAiABKAkiTQoKQ2hhbm5lbEFyZxIMCgRuYW1lGAEg", + "ASgJEhMKCXN0cl92YWx1ZRgCIAEoCUgAEhMKCWludF92YWx1ZRgDIAEoBUgA", + "QgcKBXZhbHVlIqAECgxDbGllbnRDb25maWcSFgoOc2VydmVyX3RhcmdldHMY", + "ASADKAkSLQoLY2xpZW50X3R5cGUYAiABKA4yGC5ncnBjLnRlc3RpbmcuQ2xp", + "ZW50VHlwZRI1Cg9zZWN1cml0eV9wYXJhbXMYAyABKAsyHC5ncnBjLnRlc3Rp", + "bmcuU2VjdXJpdHlQYXJhbXMSJAocb3V0c3RhbmRpbmdfcnBjc19wZXJfY2hh", + "bm5lbBgEIAEoBRIXCg9jbGllbnRfY2hhbm5lbHMYBSABKAUSHAoUYXN5bmNf", + "Y2xpZW50X3RocmVhZHMYByABKAUSJwoIcnBjX3R5cGUYCCABKA4yFS5ncnBj", + "LnRlc3RpbmcuUnBjVHlwZRItCgtsb2FkX3BhcmFtcxgKIAEoCzIYLmdycGMu", + "dGVzdGluZy5Mb2FkUGFyYW1zEjMKDnBheWxvYWRfY29uZmlnGAsgASgLMhsu", + "Z3JwYy50ZXN0aW5nLlBheWxvYWRDb25maWcSNwoQaGlzdG9ncmFtX3BhcmFt", + "cxgMIAEoCzIdLmdycGMudGVzdGluZy5IaXN0b2dyYW1QYXJhbXMSEQoJY29y", + "ZV9saXN0GA0gAygFEhIKCmNvcmVfbGltaXQYDiABKAUSGAoQb3RoZXJfY2xp", + "ZW50X2FwaRgPIAEoCRIuCgxjaGFubmVsX2FyZ3MYECADKAsyGC5ncnBjLnRl", + "c3RpbmcuQ2hhbm5lbEFyZyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASAB", + "KAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNl", + "dBgBIAEoCCJoCgpDbGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50", + "ZXN0aW5nLkNsaWVudENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRl", + "c3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUitAIKDFNlcnZlckNvbmZpZxItCgtz", + "ZXJ2ZXJfdHlwZRgBIAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUK", + "D3NlY3VyaXR5X3BhcmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0", + "eVBhcmFtcxIMCgRwb3J0GAQgASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRz", + "GAcgASgFEhIKCmNvcmVfbGltaXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcY", + "CSABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xp", + "c3QYCiADKAUSGAoQb3RoZXJfc2VydmVyX2FwaRgLIAEoCRIcChNyZXNvdXJj", + "ZV9xdW90YV9zaXplGOkHIAEoBSJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEg", + "ASgLMhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiAB", + "KAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVy", + "U3RhdHVzEigKBXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0", + "YXRzEgwKBHBvcnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVl", + "c3QiHQoMQ29yZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEK", + "CFNjZW5hcmlvEgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEo", + "CzIaLmdycGMudGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMY", + "AyABKAUSMQoNc2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5T", + "ZXJ2ZXJDb25maWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3Nl", + "Y29uZHMYBiABKAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bh", + "d25fbG9jYWxfd29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglz", + "Y2VuYXJpb3MYASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8i+AIKFVNj", + "ZW5hcmlvUmVzdWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9z", + "ZXJ2ZXJfY29yZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAES", + "GAoQc2VydmVyX3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3Rp", + "bWUYBSABKAESGAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5", + "XzUwGAcgASgBEhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJ", + "IAEoARISCgpsYXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgB", + "EhgKEHNlcnZlcl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1", + "ZXN0c19wZXJfc2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJf", + "c2Vjb25kGA4gASgBIoMDCg5TY2VuYXJpb1Jlc3VsdBIoCghzY2VuYXJpbxgB", + "IAEoCzIWLmdycGMudGVzdGluZy5TY2VuYXJpbxIuCglsYXRlbmNpZXMYAiAB", + "KAsyGy5ncnBjLnRlc3RpbmcuSGlzdG9ncmFtRGF0YRIvCgxjbGllbnRfc3Rh", + "dHMYAyADKAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHMSLwoMc2VydmVy", + "X3N0YXRzGAQgAygLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEhQKDHNl", + "cnZlcl9jb3JlcxgFIAMoBRI0CgdzdW1tYXJ5GAYgASgLMiMuZ3JwYy50ZXN0", + "aW5nLlNjZW5hcmlvUmVzdWx0U3VtbWFyeRIWCg5jbGllbnRfc3VjY2VzcxgH", + "IAMoCBIWCg5zZXJ2ZXJfc3VjY2VzcxgIIAMoCBI5Cg9yZXF1ZXN0X3Jlc3Vs", + "dHMYCSADKAsyIC5ncnBjLnRlc3RpbmcuUmVxdWVzdFJlc3VsdENvdW50KkEK", + "CkNsaWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQ", + "ARIQCgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VS", + "VkVSEAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJW", + "RVIQAhIQCgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAAS", + "DQoJU1RSRUFNSU5HEAFiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] { @@ -94,7 +97,8 @@ namespace Grpc.Testing { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), global::Grpc.Testing.ClosedLoopParams.Parser, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null), @@ -116,13 +120,13 @@ namespace Grpc.Testing { #region Enums public enum ClientType { /// - /// Many languages support a basic distinction between using - /// sync or async client, and this allows the specification + /// Many languages support a basic distinction between using + /// sync or async client, and this allows the specification /// [pbr::OriginalName("SYNC_CLIENT")] SyncClient = 0, [pbr::OriginalName("ASYNC_CLIENT")] AsyncClient = 1, /// - /// used for some language-specific variants + /// used for some language-specific variants /// [pbr::OriginalName("OTHER_CLIENT")] OtherClient = 2, } @@ -132,7 +136,7 @@ namespace Grpc.Testing { [pbr::OriginalName("ASYNC_SERVER")] AsyncServer = 1, [pbr::OriginalName("ASYNC_GENERIC_SERVER")] AsyncGenericServer = 2, /// - /// used for some language-specific variants + /// used for some language-specific variants /// [pbr::OriginalName("OTHER_SERVER")] OtherServer = 3, } @@ -146,8 +150,8 @@ namespace Grpc.Testing { #region Messages /// - /// Parameters of poisson process distribution, which is a good representation - /// of activity coming in from independent identical stationary sources. + /// Parameters of poisson process distribution, which is a good representation + /// of activity coming in from independent identical stationary sources. /// public sealed partial class PoissonParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PoissonParams()); @@ -185,7 +189,7 @@ namespace Grpc.Testing { public const int OfferedLoadFieldNumber = 1; private double offeredLoad_; /// - /// The rate of arrivals (a.k.a. lambda parameter of the exp distribution). + /// The rate of arrivals (a.k.a. lambda parameter of the exp distribution). /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double OfferedLoad { @@ -270,8 +274,8 @@ namespace Grpc.Testing { } /// - /// Once an RPC finishes, immediately start a new one. - /// No configuration parameters needed. + /// Once an RPC finishes, immediately start a new one. + /// No configuration parameters needed. /// public sealed partial class ClosedLoopParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClosedLoopParams()); @@ -549,7 +553,7 @@ namespace Grpc.Testing { } /// - /// presence of SecurityParams implies use of TLS + /// presence of SecurityParams implies use of TLS /// public sealed partial class SecurityParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SecurityParams()); @@ -696,6 +700,210 @@ namespace Grpc.Testing { } + public sealed partial class ChannelArg : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ChannelArg()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ChannelArg() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ChannelArg(ChannelArg other) : this() { + name_ = other.name_; + switch (other.ValueCase) { + case ValueOneofCase.StrValue: + StrValue = other.StrValue; + break; + case ValueOneofCase.IntValue: + IntValue = other.IntValue; + break; + } + + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ChannelArg Clone() { + return new ChannelArg(this); + } + + /// Field number for the "name" field. + public const int NameFieldNumber = 1; + private string name_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Name { + get { return name_; } + set { + name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "str_value" field. + public const int StrValueFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string StrValue { + get { return valueCase_ == ValueOneofCase.StrValue ? (string) value_ : ""; } + set { + value_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + valueCase_ = ValueOneofCase.StrValue; + } + } + + /// Field number for the "int_value" field. + public const int IntValueFieldNumber = 3; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int IntValue { + get { return valueCase_ == ValueOneofCase.IntValue ? (int) value_ : 0; } + set { + value_ = value; + valueCase_ = ValueOneofCase.IntValue; + } + } + + private object value_; + /// Enum of possible cases for the "value" oneof. + public enum ValueOneofCase { + None = 0, + StrValue = 2, + IntValue = 3, + } + private ValueOneofCase valueCase_ = ValueOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ValueOneofCase ValueCase { + get { return valueCase_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearValue() { + valueCase_ = ValueOneofCase.None; + value_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as ChannelArg); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(ChannelArg other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Name != other.Name) return false; + if (StrValue != other.StrValue) return false; + if (IntValue != other.IntValue) return false; + if (ValueCase != other.ValueCase) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Name.Length != 0) hash ^= Name.GetHashCode(); + if (valueCase_ == ValueOneofCase.StrValue) hash ^= StrValue.GetHashCode(); + if (valueCase_ == ValueOneofCase.IntValue) hash ^= IntValue.GetHashCode(); + hash ^= (int) valueCase_; + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (valueCase_ == ValueOneofCase.StrValue) { + output.WriteRawTag(18); + output.WriteString(StrValue); + } + if (valueCase_ == ValueOneofCase.IntValue) { + output.WriteRawTag(24); + output.WriteInt32(IntValue); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Name.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); + } + if (valueCase_ == ValueOneofCase.StrValue) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(StrValue); + } + if (valueCase_ == ValueOneofCase.IntValue) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(IntValue); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(ChannelArg other) { + if (other == null) { + return; + } + if (other.Name.Length != 0) { + Name = other.Name; + } + switch (other.ValueCase) { + case ValueOneofCase.StrValue: + StrValue = other.StrValue; + break; + case ValueOneofCase.IntValue: + IntValue = other.IntValue; + break; + } + + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + StrValue = input.ReadString(); + break; + } + case 24: { + IntValue = input.ReadInt32(); + break; + } + } + } + } + + } + public sealed partial class ClientConfig : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClientConfig()); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -703,7 +911,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -733,6 +941,7 @@ namespace Grpc.Testing { coreList_ = other.coreList_.Clone(); coreLimit_ = other.coreLimit_; otherClientApi_ = other.otherClientApi_; + channelArgs_ = other.channelArgs_.Clone(); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -746,7 +955,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForString(10); private readonly pbc::RepeatedField serverTargets_ = new pbc::RepeatedField(); /// - /// List of targets to connect to. At least one target needs to be specified. + /// List of targets to connect to. At least one target needs to be specified. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ServerTargets { @@ -779,8 +988,8 @@ namespace Grpc.Testing { public const int OutstandingRpcsPerChannelFieldNumber = 4; private int outstandingRpcsPerChannel_; /// - /// How many concurrent RPCs to start for each channel. - /// For synchronous client, use a separate thread for each outstanding RPC. + /// How many concurrent RPCs to start for each channel. + /// For synchronous client, use a separate thread for each outstanding RPC. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int OutstandingRpcsPerChannel { @@ -794,8 +1003,8 @@ namespace Grpc.Testing { public const int ClientChannelsFieldNumber = 5; private int clientChannels_; /// - /// Number of independent client channels to create. - /// i-th channel will connect to server_target[i % server_targets.size()] + /// Number of independent client channels to create. + /// i-th channel will connect to server_target[i % server_targets.size()] /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ClientChannels { @@ -809,7 +1018,7 @@ namespace Grpc.Testing { public const int AsyncClientThreadsFieldNumber = 7; private int asyncClientThreads_; /// - /// Only for async client. Number of threads to use to start/manage RPCs. + /// Only for async client. Number of threads to use to start/manage RPCs. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int AsyncClientThreads { @@ -834,7 +1043,7 @@ namespace Grpc.Testing { public const int LoadParamsFieldNumber = 10; private global::Grpc.Testing.LoadParams loadParams_; /// - /// The requested load for the entire client (aggregated over all the threads). + /// The requested load for the entire client (aggregated over all the threads). /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.LoadParams LoadParams { @@ -872,7 +1081,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForInt32(106); private readonly pbc::RepeatedField coreList_ = new pbc::RepeatedField(); /// - /// Specify the cores we should run the client on, if desired + /// Specify the cores we should run the client on, if desired /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField CoreList { @@ -894,7 +1103,7 @@ namespace Grpc.Testing { public const int OtherClientApiFieldNumber = 15; private string otherClientApi_ = ""; /// - /// If we use an OTHER_CLIENT client_type, this string gives more detail + /// If we use an OTHER_CLIENT client_type, this string gives more detail /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string OtherClientApi { @@ -904,6 +1113,16 @@ namespace Grpc.Testing { } } + /// Field number for the "channel_args" field. + public const int ChannelArgsFieldNumber = 16; + private static readonly pb::FieldCodec _repeated_channelArgs_codec + = pb::FieldCodec.ForMessage(130, global::Grpc.Testing.ChannelArg.Parser); + private readonly pbc::RepeatedField channelArgs_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField ChannelArgs { + get { return channelArgs_; } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientConfig); @@ -930,6 +1149,7 @@ namespace Grpc.Testing { if(!coreList_.Equals(other.coreList_)) return false; if (CoreLimit != other.CoreLimit) return false; if (OtherClientApi != other.OtherClientApi) return false; + if(!channelArgs_.Equals(other.channelArgs_)) return false; return true; } @@ -949,6 +1169,7 @@ namespace Grpc.Testing { hash ^= coreList_.GetHashCode(); if (CoreLimit != 0) hash ^= CoreLimit.GetHashCode(); if (OtherClientApi.Length != 0) hash ^= OtherClientApi.GetHashCode(); + hash ^= channelArgs_.GetHashCode(); return hash; } @@ -1005,6 +1226,7 @@ namespace Grpc.Testing { output.WriteRawTag(122); output.WriteString(OtherClientApi); } + channelArgs_.WriteTo(output, _repeated_channelArgs_codec); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1045,6 +1267,7 @@ namespace Grpc.Testing { if (OtherClientApi.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(OtherClientApi); } + size += channelArgs_.CalculateSize(_repeated_channelArgs_codec); return size; } @@ -1100,6 +1323,7 @@ namespace Grpc.Testing { if (other.OtherClientApi.Length != 0) { OtherClientApi = other.OtherClientApi; } + channelArgs_.Add(other.channelArgs_); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1175,6 +1399,10 @@ namespace Grpc.Testing { OtherClientApi = input.ReadString(); break; } + case 130: { + channelArgs_.AddEntriesFrom(input, _repeated_channelArgs_codec); + break; + } } } } @@ -1188,7 +1416,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1305,7 +1533,7 @@ namespace Grpc.Testing { } /// - /// Request current stats + /// Request current stats /// public sealed partial class Mark : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Mark()); @@ -1314,7 +1542,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1343,7 +1571,7 @@ namespace Grpc.Testing { public const int ResetFieldNumber = 1; private bool reset_; /// - /// if true, the stats will be reset after taking their snapshot. + /// if true, the stats will be reset after taking their snapshot. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Reset { @@ -1434,7 +1662,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1620,7 +1848,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1679,7 +1907,7 @@ namespace Grpc.Testing { public const int PortFieldNumber = 4; private int port_; /// - /// Port on which to listen. Zero means pick unused port. + /// Port on which to listen. Zero means pick unused port. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Port { @@ -1693,7 +1921,7 @@ namespace Grpc.Testing { public const int AsyncServerThreadsFieldNumber = 7; private int asyncServerThreads_; /// - /// Only for async server. Number of threads used to serve the requests. + /// Only for async server. Number of threads used to serve the requests. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int AsyncServerThreads { @@ -1707,7 +1935,7 @@ namespace Grpc.Testing { public const int CoreLimitFieldNumber = 8; private int coreLimit_; /// - /// Specify the number of cores to limit server to, if desired + /// Specify the number of cores to limit server to, if desired /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CoreLimit { @@ -1721,7 +1949,10 @@ namespace Grpc.Testing { public const int PayloadConfigFieldNumber = 9; private global::Grpc.Testing.PayloadConfig payloadConfig_; /// - /// payload config, used in generic server + /// payload config, used in generic server. + /// Note this must NOT be used in proto (non-generic) servers. For proto servers, + /// 'response sizes' must be configured from the 'response_size' field of the + /// 'SimpleRequest' objects in RPC requests. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadConfig PayloadConfig { @@ -1737,7 +1968,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForInt32(82); private readonly pbc::RepeatedField coreList_ = new pbc::RepeatedField(); /// - /// Specify the cores we should run the server on, if desired + /// Specify the cores we should run the server on, if desired /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField CoreList { @@ -1748,7 +1979,7 @@ namespace Grpc.Testing { public const int OtherServerApiFieldNumber = 11; private string otherServerApi_ = ""; /// - /// If we use an OTHER_SERVER client_type, this string gives more detail + /// If we use an OTHER_SERVER client_type, this string gives more detail /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string OtherServerApi { @@ -1762,7 +1993,7 @@ namespace Grpc.Testing { public const int ResourceQuotaSizeFieldNumber = 1001; private int resourceQuotaSize_; /// - /// Buffer pool size (no buffer pool specified if unset) + /// Buffer pool size (no buffer pool specified if unset) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ResourceQuotaSize { @@ -1987,7 +2218,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2173,7 +2404,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2215,7 +2446,7 @@ namespace Grpc.Testing { public const int PortFieldNumber = 2; private int port_; /// - /// the port bound by the server + /// the port bound by the server /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Port { @@ -2229,7 +2460,7 @@ namespace Grpc.Testing { public const int CoresFieldNumber = 3; private int cores_; /// - /// Number of cores available to the server + /// Number of cores available to the server /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Cores { @@ -2358,7 +2589,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2447,7 +2678,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2476,7 +2707,7 @@ namespace Grpc.Testing { public const int CoresFieldNumber = 1; private int cores_; /// - /// Number of cores available on the server + /// Number of cores available on the server /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Cores { @@ -2567,7 +2798,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2650,7 +2881,7 @@ namespace Grpc.Testing { } /// - /// A single performance scenario: input to qps_json_driver + /// A single performance scenario: input to qps_json_driver /// public sealed partial class Scenario : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Scenario()); @@ -2659,7 +2890,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2695,7 +2926,7 @@ namespace Grpc.Testing { public const int NameFieldNumber = 1; private string name_ = ""; /// - /// Human readable name for this scenario + /// Human readable name for this scenario /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { @@ -2709,7 +2940,7 @@ namespace Grpc.Testing { public const int ClientConfigFieldNumber = 2; private global::Grpc.Testing.ClientConfig clientConfig_; /// - /// Client configuration + /// Client configuration /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ClientConfig ClientConfig { @@ -2723,7 +2954,7 @@ namespace Grpc.Testing { public const int NumClientsFieldNumber = 3; private int numClients_; /// - /// Number of clients to start for the test + /// Number of clients to start for the test /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int NumClients { @@ -2737,7 +2968,7 @@ namespace Grpc.Testing { public const int ServerConfigFieldNumber = 4; private global::Grpc.Testing.ServerConfig serverConfig_; /// - /// Server configuration + /// Server configuration /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ServerConfig ServerConfig { @@ -2751,7 +2982,7 @@ namespace Grpc.Testing { public const int NumServersFieldNumber = 5; private int numServers_; /// - /// Number of servers to start for the test + /// Number of servers to start for the test /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int NumServers { @@ -2765,7 +2996,7 @@ namespace Grpc.Testing { public const int WarmupSecondsFieldNumber = 6; private int warmupSeconds_; /// - /// Warmup period, in seconds + /// Warmup period, in seconds /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int WarmupSeconds { @@ -2779,7 +3010,7 @@ namespace Grpc.Testing { public const int BenchmarkSecondsFieldNumber = 7; private int benchmarkSeconds_; /// - /// Benchmark time, in seconds + /// Benchmark time, in seconds /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int BenchmarkSeconds { @@ -2793,7 +3024,7 @@ namespace Grpc.Testing { public const int SpawnLocalWorkerCountFieldNumber = 8; private int spawnLocalWorkerCount_; /// - /// Number of workers to spawn locally (usually zero) + /// Number of workers to spawn locally (usually zero) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int SpawnLocalWorkerCount { @@ -3002,7 +3233,7 @@ namespace Grpc.Testing { } /// - /// A set of scenarios to be run with qps_json_driver + /// A set of scenarios to be run with qps_json_driver /// public sealed partial class Scenarios : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Scenarios()); @@ -3011,7 +3242,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3114,8 +3345,8 @@ namespace Grpc.Testing { } /// - /// Basic summary that can be computed from ClientStats and ServerStats - /// once the scenario has finished. + /// Basic summary that can be computed from ClientStats and ServerStats + /// once the scenario has finished. /// public sealed partial class ScenarioResultSummary : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ScenarioResultSummary()); @@ -3124,7 +3355,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3166,7 +3397,7 @@ namespace Grpc.Testing { public const int QpsFieldNumber = 1; private double qps_; /// - /// Total number of operations per second over all clients. + /// Total number of operations per second over all clients. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Qps { @@ -3180,7 +3411,7 @@ namespace Grpc.Testing { public const int QpsPerServerCoreFieldNumber = 2; private double qpsPerServerCore_; /// - /// QPS per one server core. + /// QPS per one server core. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double QpsPerServerCore { @@ -3194,7 +3425,7 @@ namespace Grpc.Testing { public const int ServerSystemTimeFieldNumber = 3; private double serverSystemTime_; /// - /// server load based on system_time (0.85 => 85%) + /// server load based on system_time (0.85 => 85%) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ServerSystemTime { @@ -3208,7 +3439,7 @@ namespace Grpc.Testing { public const int ServerUserTimeFieldNumber = 4; private double serverUserTime_; /// - /// server load based on user_time (0.85 => 85%) + /// server load based on user_time (0.85 => 85%) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ServerUserTime { @@ -3222,7 +3453,7 @@ namespace Grpc.Testing { public const int ClientSystemTimeFieldNumber = 5; private double clientSystemTime_; /// - /// client load based on system_time (0.85 => 85%) + /// client load based on system_time (0.85 => 85%) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ClientSystemTime { @@ -3236,7 +3467,7 @@ namespace Grpc.Testing { public const int ClientUserTimeFieldNumber = 6; private double clientUserTime_; /// - /// client load based on user_time (0.85 => 85%) + /// client load based on user_time (0.85 => 85%) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ClientUserTime { @@ -3250,7 +3481,7 @@ namespace Grpc.Testing { public const int Latency50FieldNumber = 7; private double latency50_; /// - /// X% latency percentiles (in nanoseconds) + /// X% latency percentiles (in nanoseconds) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Latency50 { @@ -3308,7 +3539,7 @@ namespace Grpc.Testing { public const int ServerCpuUsageFieldNumber = 12; private double serverCpuUsage_; /// - /// server cpu usage percentage + /// server cpu usage percentage /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ServerCpuUsage { @@ -3322,7 +3553,7 @@ namespace Grpc.Testing { public const int SuccessfulRequestsPerSecondFieldNumber = 13; private double successfulRequestsPerSecond_; /// - /// Number of requests that succeeded/failed + /// Number of requests that succeeded/failed /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double SuccessfulRequestsPerSecond { @@ -3626,7 +3857,7 @@ namespace Grpc.Testing { } /// - /// Results of a single benchmark scenario. + /// Results of a single benchmark scenario. /// public sealed partial class ScenarioResult : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ScenarioResult()); @@ -3635,7 +3866,7 @@ namespace Grpc.Testing { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; } + get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[18]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3672,7 +3903,7 @@ namespace Grpc.Testing { public const int ScenarioFieldNumber = 1; private global::Grpc.Testing.Scenario scenario_; /// - /// Inputs used to run the scenario. + /// Inputs used to run the scenario. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Scenario Scenario { @@ -3686,7 +3917,7 @@ namespace Grpc.Testing { public const int LatenciesFieldNumber = 2; private global::Grpc.Testing.HistogramData latencies_; /// - /// Histograms from all clients merged into one histogram. + /// Histograms from all clients merged into one histogram. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.HistogramData Latencies { @@ -3702,7 +3933,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForMessage(26, global::Grpc.Testing.ClientStats.Parser); private readonly pbc::RepeatedField clientStats_ = new pbc::RepeatedField(); /// - /// Client stats for each client + /// Client stats for each client /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ClientStats { @@ -3715,7 +3946,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForMessage(34, global::Grpc.Testing.ServerStats.Parser); private readonly pbc::RepeatedField serverStats_ = new pbc::RepeatedField(); /// - /// Server stats for each server + /// Server stats for each server /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ServerStats { @@ -3728,7 +3959,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForInt32(42); private readonly pbc::RepeatedField serverCores_ = new pbc::RepeatedField(); /// - /// Number of cores available to each server + /// Number of cores available to each server /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ServerCores { @@ -3739,7 +3970,7 @@ namespace Grpc.Testing { public const int SummaryFieldNumber = 6; private global::Grpc.Testing.ScenarioResultSummary summary_; /// - /// An after-the-fact computed summary + /// An after-the-fact computed summary /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ScenarioResultSummary Summary { @@ -3755,7 +3986,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForBool(58); private readonly pbc::RepeatedField clientSuccess_ = new pbc::RepeatedField(); /// - /// Information on success or failure of each worker + /// Information on success or failure of each worker /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ClientSuccess { @@ -3778,7 +4009,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForMessage(74, global::Grpc.Testing.RequestResultCount.Parser); private readonly pbc::RepeatedField requestResults_ = new pbc::RepeatedField(); /// - /// Number of failed requests (one row per status code seen) + /// Number of failed requests (one row per status code seen) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField RequestResults { diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs index 3017e664b90..24ffd617417 100644 --- a/src/csharp/Grpc.IntegrationTesting/Empty.cs +++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs @@ -35,13 +35,13 @@ namespace Grpc.Testing { } #region Messages /// - /// An empty message that you can re-use to avoid defining duplicated empty - /// messages in your project. A typical example is to use it as argument or the - /// return value of a service API. For instance: + /// An empty message that you can re-use to avoid defining duplicated empty + /// messages in your project. A typical example is to use it as argument or the + /// return value of a service API. For instance: /// - /// service Foo { - /// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; - /// }; + /// service Foo { + /// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; + /// }; /// public sealed partial class Empty : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Empty()); diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index f7abcf80469..38b9a5d3c59 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -33,53 +33,47 @@ - - ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - - - ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll - - - ..\packages\CommandLineParser.Unofficial.2.0.275\lib\net45\CommandLineParser.Unofficial.dll + + ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll + + ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll - ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - - - ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll + ..\packages\Google.Apis.Core.1.21.0\lib\net45\Google.Apis.Core.dll - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll + ..\packages\Google.Apis.1.21.0\lib\net45\Google.Apis.dll - ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll + ..\packages\Google.Apis.1.21.0\lib\net45\Google.Apis.PlatformServices.dll - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll + ..\packages\Google.Apis.Auth.1.21.0\lib\net45\Google.Apis.Auth.dll - ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + ..\packages\Google.Apis.Auth.1.21.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll + + + ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll + + + ..\packages\NUnitLite.3.6.0\lib\net45\nunitlite.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll + ..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll - ..\packages\Moq.4.6.38-alpha\lib\net45\Moq.dll + ..\packages\Moq.4.7.0\lib\net45\Moq.dll - - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + ..\packages\CommandLineParser.2.1.1-beta\lib\net45\CommandLine.dll diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs index 369fe738d6c..278ef662e47 100644 --- a/src/csharp/Grpc.IntegrationTesting/Messages.cs +++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs @@ -75,12 +75,12 @@ namespace Grpc.Testing { } #region Enums /// - /// DEPRECATED, don't use. To be removed shortly. - /// The type of payload that should be returned. + /// DEPRECATED, don't use. To be removed shortly. + /// The type of payload that should be returned. /// public enum PayloadType { /// - /// Compressable text format. + /// Compressable text format. /// [pbr::OriginalName("COMPRESSABLE")] Compressable = 0, } @@ -89,9 +89,9 @@ namespace Grpc.Testing { #region Messages /// - /// TODO(dgq): Go back to using well-known types once - /// https://github.com/grpc/grpc/issues/6980 has been fixed. - /// import "google/protobuf/wrappers.proto"; + /// TODO(dgq): Go back to using well-known types once + /// https://github.com/grpc/grpc/issues/6980 has been fixed. + /// import "google/protobuf/wrappers.proto"; /// public sealed partial class BoolValue : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BoolValue()); @@ -129,7 +129,7 @@ namespace Grpc.Testing { public const int ValueFieldNumber = 1; private bool value_; /// - /// The bool value. + /// The bool value. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Value { @@ -214,7 +214,7 @@ namespace Grpc.Testing { } /// - /// A block of data, to simply increase gRPC message size. + /// A block of data, to simply increase gRPC message size. /// public sealed partial class Payload : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Payload()); @@ -253,8 +253,8 @@ namespace Grpc.Testing { public const int TypeFieldNumber = 1; private global::Grpc.Testing.PayloadType type_ = 0; /// - /// DEPRECATED, don't use. To be removed shortly. - /// The type of data in body. + /// DEPRECATED, don't use. To be removed shortly. + /// The type of data in body. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadType Type { @@ -268,7 +268,7 @@ namespace Grpc.Testing { public const int BodyFieldNumber = 2; private pb::ByteString body_ = pb::ByteString.Empty; /// - /// Primary contents of payload. + /// Primary contents of payload. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pb::ByteString Body { @@ -369,8 +369,8 @@ namespace Grpc.Testing { } /// - /// A protobuf representation for grpc status. This is used by test - /// clients to specify a status that the server should attempt to return. + /// A protobuf representation for grpc status. This is used by test + /// clients to specify a status that the server should attempt to return. /// public sealed partial class EchoStatus : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EchoStatus()); @@ -518,7 +518,7 @@ namespace Grpc.Testing { } /// - /// Unary request. + /// Unary request. /// public sealed partial class SimpleRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SimpleRequest()); @@ -563,9 +563,9 @@ namespace Grpc.Testing { public const int ResponseTypeFieldNumber = 1; private global::Grpc.Testing.PayloadType responseType_ = 0; /// - /// DEPRECATED, don't use. To be removed shortly. - /// Desired payload type in the response from the server. - /// If response_type is RANDOM, server randomly chooses one from other formats. + /// DEPRECATED, don't use. To be removed shortly. + /// Desired payload type in the response from the server. + /// If response_type is RANDOM, server randomly chooses one from other formats. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadType ResponseType { @@ -579,7 +579,7 @@ namespace Grpc.Testing { public const int ResponseSizeFieldNumber = 2; private int responseSize_; /// - /// Desired payload size in the response from the server. + /// Desired payload size in the response from the server. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ResponseSize { @@ -593,7 +593,7 @@ namespace Grpc.Testing { public const int PayloadFieldNumber = 3; private global::Grpc.Testing.Payload payload_; /// - /// Optional input payload sent along with the request. + /// Optional input payload sent along with the request. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { @@ -607,7 +607,7 @@ namespace Grpc.Testing { public const int FillUsernameFieldNumber = 4; private bool fillUsername_; /// - /// Whether SimpleResponse should include username. + /// Whether SimpleResponse should include username. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool FillUsername { @@ -621,7 +621,7 @@ namespace Grpc.Testing { public const int FillOauthScopeFieldNumber = 5; private bool fillOauthScope_; /// - /// Whether SimpleResponse should include OAuth scope. + /// Whether SimpleResponse should include OAuth scope. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool FillOauthScope { @@ -635,10 +635,10 @@ namespace Grpc.Testing { public const int ResponseCompressedFieldNumber = 6; private global::Grpc.Testing.BoolValue responseCompressed_; /// - /// Whether to request the server to compress the response. This field is - /// "nullable" in order to interoperate seamlessly with clients not able to - /// implement the full compression tests by introspecting the call to verify - /// the response's compression status. + /// Whether to request the server to compress the response. This field is + /// "nullable" in order to interoperate seamlessly with clients not able to + /// implement the full compression tests by introspecting the call to verify + /// the response's compression status. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue ResponseCompressed { @@ -652,7 +652,7 @@ namespace Grpc.Testing { public const int ResponseStatusFieldNumber = 7; private global::Grpc.Testing.EchoStatus responseStatus_; /// - /// Whether server should return a given status + /// Whether server should return a given status /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.EchoStatus ResponseStatus { @@ -666,7 +666,7 @@ namespace Grpc.Testing { public const int ExpectCompressedFieldNumber = 8; private global::Grpc.Testing.BoolValue expectCompressed_; /// - /// Whether the server should expect this request to be compressed. + /// Whether the server should expect this request to be compressed. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue ExpectCompressed { @@ -887,7 +887,7 @@ namespace Grpc.Testing { } /// - /// Unary response, as configured by the request. + /// Unary response, as configured by the request. /// public sealed partial class SimpleResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SimpleResponse()); @@ -927,7 +927,7 @@ namespace Grpc.Testing { public const int PayloadFieldNumber = 1; private global::Grpc.Testing.Payload payload_; /// - /// Payload to increase message size. + /// Payload to increase message size. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { @@ -941,8 +941,8 @@ namespace Grpc.Testing { public const int UsernameFieldNumber = 2; private string username_ = ""; /// - /// The user the request came from, for verifying authentication was - /// successful when the client expected it. + /// The user the request came from, for verifying authentication was + /// successful when the client expected it. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Username { @@ -956,7 +956,7 @@ namespace Grpc.Testing { public const int OauthScopeFieldNumber = 3; private string oauthScope_ = ""; /// - /// OAuth scope. + /// OAuth scope. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string OauthScope { @@ -1079,7 +1079,7 @@ namespace Grpc.Testing { } /// - /// Client-streaming request. + /// Client-streaming request. /// public sealed partial class StreamingInputCallRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingInputCallRequest()); @@ -1118,7 +1118,7 @@ namespace Grpc.Testing { public const int PayloadFieldNumber = 1; private global::Grpc.Testing.Payload payload_; /// - /// Optional input payload sent along with the request. + /// Optional input payload sent along with the request. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { @@ -1132,10 +1132,10 @@ namespace Grpc.Testing { public const int ExpectCompressedFieldNumber = 2; private global::Grpc.Testing.BoolValue expectCompressed_; /// - /// Whether the server should expect this request to be compressed. This field - /// is "nullable" in order to interoperate seamlessly with servers not able to - /// implement the full compression tests by introspecting the call to verify - /// the request's compression status. + /// Whether the server should expect this request to be compressed. This field + /// is "nullable" in order to interoperate seamlessly with servers not able to + /// implement the full compression tests by introspecting the call to verify + /// the request's compression status. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue ExpectCompressed { @@ -1248,7 +1248,7 @@ namespace Grpc.Testing { } /// - /// Client-streaming response. + /// Client-streaming response. /// public sealed partial class StreamingInputCallResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingInputCallResponse()); @@ -1286,7 +1286,7 @@ namespace Grpc.Testing { public const int AggregatedPayloadSizeFieldNumber = 1; private int aggregatedPayloadSize_; /// - /// Aggregated size of payloads received from the client. + /// Aggregated size of payloads received from the client. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int AggregatedPayloadSize { @@ -1371,7 +1371,7 @@ namespace Grpc.Testing { } /// - /// Configuration for a particular response. + /// Configuration for a particular response. /// public sealed partial class ResponseParameters : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ResponseParameters()); @@ -1411,7 +1411,7 @@ namespace Grpc.Testing { public const int SizeFieldNumber = 1; private int size_; /// - /// Desired payload sizes in responses from the server. + /// Desired payload sizes in responses from the server. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Size { @@ -1425,8 +1425,8 @@ namespace Grpc.Testing { public const int IntervalUsFieldNumber = 2; private int intervalUs_; /// - /// Desired interval between consecutive responses in the response stream in - /// microseconds. + /// Desired interval between consecutive responses in the response stream in + /// microseconds. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int IntervalUs { @@ -1440,10 +1440,10 @@ namespace Grpc.Testing { public const int CompressedFieldNumber = 3; private global::Grpc.Testing.BoolValue compressed_; /// - /// Whether to request the server to compress the response. This field is - /// "nullable" in order to interoperate seamlessly with clients not able to - /// implement the full compression tests by introspecting the call to verify - /// the response's compression status. + /// Whether to request the server to compress the response. This field is + /// "nullable" in order to interoperate seamlessly with clients not able to + /// implement the full compression tests by introspecting the call to verify + /// the response's compression status. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue Compressed { @@ -1566,7 +1566,7 @@ namespace Grpc.Testing { } /// - /// Server-streaming request. + /// Server-streaming request. /// public sealed partial class StreamingOutputCallRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingOutputCallRequest()); @@ -1607,11 +1607,11 @@ namespace Grpc.Testing { public const int ResponseTypeFieldNumber = 1; private global::Grpc.Testing.PayloadType responseType_ = 0; /// - /// DEPRECATED, don't use. To be removed shortly. - /// Desired payload type in the response from the server. - /// If response_type is RANDOM, the payload from each response in the stream - /// might be of different types. This is to simulate a mixed type of payload - /// stream. + /// DEPRECATED, don't use. To be removed shortly. + /// Desired payload type in the response from the server. + /// If response_type is RANDOM, the payload from each response in the stream + /// might be of different types. This is to simulate a mixed type of payload + /// stream. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadType ResponseType { @@ -1627,7 +1627,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForMessage(18, global::Grpc.Testing.ResponseParameters.Parser); private readonly pbc::RepeatedField responseParameters_ = new pbc::RepeatedField(); /// - /// Configuration for each expected response message. + /// Configuration for each expected response message. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ResponseParameters { @@ -1638,7 +1638,7 @@ namespace Grpc.Testing { public const int PayloadFieldNumber = 3; private global::Grpc.Testing.Payload payload_; /// - /// Optional input payload sent along with the request. + /// Optional input payload sent along with the request. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { @@ -1652,7 +1652,7 @@ namespace Grpc.Testing { public const int ResponseStatusFieldNumber = 7; private global::Grpc.Testing.EchoStatus responseStatus_; /// - /// Whether server should return a given status + /// Whether server should return a given status /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.EchoStatus ResponseStatus { @@ -1790,7 +1790,7 @@ namespace Grpc.Testing { } /// - /// Server-streaming response, as configured by the request and parameters. + /// Server-streaming response, as configured by the request and parameters. /// public sealed partial class StreamingOutputCallResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingOutputCallResponse()); @@ -1828,7 +1828,7 @@ namespace Grpc.Testing { public const int PayloadFieldNumber = 1; private global::Grpc.Testing.Payload payload_; /// - /// Payload to increase response size. + /// Payload to increase response size. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { @@ -1919,8 +1919,8 @@ namespace Grpc.Testing { } /// - /// For reconnect interop test only. - /// Client tells server what reconnection parameters it used. + /// For reconnect interop test only. + /// Client tells server what reconnection parameters it used. /// public sealed partial class ReconnectParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReconnectParams()); @@ -2040,9 +2040,9 @@ namespace Grpc.Testing { } /// - /// For reconnect interop test only. - /// Server tells client whether its reconnects are following the spec and the - /// reconnect backoffs it saw. + /// For reconnect interop test only. + /// Server tells client whether its reconnects are following the spec and the + /// reconnect backoffs it saw. /// public sealed partial class ReconnectInfo : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReconnectInfo()); diff --git a/src/csharp/Grpc.IntegrationTesting/Metrics.cs b/src/csharp/Grpc.IntegrationTesting/Metrics.cs index 4de1847e5fb..84eb09af4fb 100644 --- a/src/csharp/Grpc.IntegrationTesting/Metrics.cs +++ b/src/csharp/Grpc.IntegrationTesting/Metrics.cs @@ -44,7 +44,7 @@ namespace Grpc.Testing { } #region Messages /// - /// Reponse message containing the gauge name and value + /// Reponse message containing the gauge name and value /// public sealed partial class GaugeResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GaugeResponse()); @@ -282,7 +282,7 @@ namespace Grpc.Testing { } /// - /// Request message containing the gauge name + /// Request message containing the gauge name /// public sealed partial class GaugeRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GaugeRequest()); diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs index 7aef35cda31..f918b9576bd 100644 --- a/src/csharp/Grpc.IntegrationTesting/Payloads.cs +++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs @@ -335,8 +335,8 @@ namespace Grpc.Testing { } /// - /// TODO (vpai): Fill this in once the details of complex, representative - /// protos are decided + /// TODO (vpai): Fill this in once the details of complex, representative + /// protos are decided /// public sealed partial class ComplexProtoParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ComplexProtoParams()); diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index f85e272711f..377dad63f40 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -37,6 +37,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Google.Protobuf; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Testing; @@ -68,7 +69,7 @@ namespace Grpc.IntegrationTesting server = new Server { - Services = { TestService.BindService(new TestServiceImpl()) }, + Services = { TestService.BindService(new SslCredentialsTestServiceImpl()) }, Ports = { { Host, ServerPort.PickUnused, serverCredentials } } }; server.Start(); @@ -95,5 +96,40 @@ namespace Grpc.IntegrationTesting var response = client.UnaryCall(new SimpleRequest { ResponseSize = 10 }); Assert.AreEqual(10, response.Payload.Body.Length); } + + [Test] + public async Task AuthContextIsPopulated() + { + var call = client.StreamingInputCall(); + await call.RequestStream.CompleteAsync(); + var response = await call.ResponseAsync; + Assert.AreEqual(12345, response.AggregatedPayloadSize); + } + + private class SslCredentialsTestServiceImpl : TestService.TestServiceBase + { + public override async Task UnaryCall(SimpleRequest request, ServerCallContext context) + { + return new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) }; + } + + public override async Task StreamingInputCall(IAsyncStreamReader requestStream, ServerCallContext context) + { + var authContext = context.AuthContext; + await requestStream.ForEachAsync(async request => {}); + + Assert.IsTrue(authContext.IsPeerAuthenticated); + Assert.AreEqual("x509_subject_alternative_name", authContext.PeerIdentityPropertyName); + Assert.IsTrue(authContext.PeerIdentity.Count() > 0); + Assert.AreEqual("ssl", authContext.FindPropertiesByName("transport_security_type").First().Value); + + return new StreamingInputCallResponse { AggregatedPayloadSize = 12345 }; + } + + private static Payload CreateZerosPayload(int size) + { + return new Payload { Body = ByteString.CopyFrom(new byte[size]) }; + } + } } } diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs index 504aa11d8a7..79ff220436a 100644 --- a/src/csharp/Grpc.IntegrationTesting/Stats.cs +++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs @@ -90,7 +90,7 @@ namespace Grpc.Testing { public const int TimeElapsedFieldNumber = 1; private double timeElapsed_; /// - /// wall clock time change in seconds since last reset + /// wall clock time change in seconds since last reset /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeElapsed { @@ -104,7 +104,7 @@ namespace Grpc.Testing { public const int TimeUserFieldNumber = 2; private double timeUser_; /// - /// change in user time (in seconds) used by the server since last reset + /// change in user time (in seconds) used by the server since last reset /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeUser { @@ -118,8 +118,8 @@ namespace Grpc.Testing { public const int TimeSystemFieldNumber = 3; private double timeSystem_; /// - /// change in server time (in seconds) used by the server process and all - /// threads since last reset + /// change in server time (in seconds) used by the server process and all + /// threads since last reset /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeSystem { @@ -133,7 +133,7 @@ namespace Grpc.Testing { public const int TotalCpuTimeFieldNumber = 4; private ulong totalCpuTime_; /// - /// change in total cpu time of the server (data from proc/stat) + /// change in total cpu time of the server (data from proc/stat) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ulong TotalCpuTime { @@ -147,7 +147,7 @@ namespace Grpc.Testing { public const int IdleCpuTimeFieldNumber = 5; private ulong idleCpuTime_; /// - /// change in idle time of the server (data from proc/stat) + /// change in idle time of the server (data from proc/stat) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ulong IdleCpuTime { @@ -296,7 +296,7 @@ namespace Grpc.Testing { } /// - /// Histogram params based on grpc/support/histogram.c + /// Histogram params based on grpc/support/histogram.c /// public sealed partial class HistogramParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HistogramParams()); @@ -335,7 +335,7 @@ namespace Grpc.Testing { public const int ResolutionFieldNumber = 1; private double resolution_; /// - /// first bucket is [0, 1 + resolution) + /// first bucket is [0, 1 + resolution) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Resolution { @@ -349,7 +349,7 @@ namespace Grpc.Testing { public const int MaxPossibleFieldNumber = 2; private double maxPossible_; /// - /// use enough buckets to allow this value + /// use enough buckets to allow this value /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double MaxPossible { @@ -450,7 +450,7 @@ namespace Grpc.Testing { } /// - /// Histogram data based on grpc/support/histogram.c + /// Histogram data based on grpc/support/histogram.c /// public sealed partial class HistogramData : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HistogramData()); @@ -887,7 +887,7 @@ namespace Grpc.Testing { public const int LatenciesFieldNumber = 1; private global::Grpc.Testing.HistogramData latencies_; /// - /// Latency histogram. Data points are in nanoseconds. + /// Latency histogram. Data points are in nanoseconds. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.HistogramData Latencies { @@ -901,7 +901,7 @@ namespace Grpc.Testing { public const int TimeElapsedFieldNumber = 2; private double timeElapsed_; /// - /// See ServerStats for details. + /// See ServerStats for details. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeElapsed { @@ -939,7 +939,7 @@ namespace Grpc.Testing { = pb::FieldCodec.ForMessage(42, global::Grpc.Testing.RequestResultCount.Parser); private readonly pbc::RepeatedField requestResults_ = new pbc::RepeatedField(); /// - /// Number of failed requests (one row per status code seen) + /// Number of failed requests (one row per status code seen) /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField RequestResults { diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config index a03ee926f47..030f9d97b89 100644 --- a/src/csharp/Grpc.IntegrationTesting/packages.config +++ b/src/csharp/Grpc.IntegrationTesting/packages.config @@ -1,17 +1,15 @@  - - - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json index eba54318a5b..40fc566adcf 100644 --- a/src/csharp/Grpc.IntegrationTesting/project.json +++ b/src/csharp/Grpc.IntegrationTesting/project.json @@ -54,18 +54,15 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0", - "CommandLineParser.Unofficial": "2.0.275", - "Moq": "4.6.38-alpha", - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "Google.Protobuf": "3.2.0", + "CommandLineParser": "2.1.1-beta", + "Moq": "4.7.0", + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } + "frameworkAssemblies": {} }, "netcoreapp1.0": { "imports": [ diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index c5918b194ef..7e2b551799e 100644 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -35,17 +35,17 @@ - - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - - - ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + + ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll - - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll + + + ..\packages\NUnitLite.3.6.0\lib\net45\nunitlite.dll diff --git a/src/csharp/Grpc.Reflection.Tests/packages.config b/src/csharp/Grpc.Reflection.Tests/packages.config index 0fed4dbd415..8a7f7a0652a 100644 --- a/src/csharp/Grpc.Reflection.Tests/packages.config +++ b/src/csharp/Grpc.Reflection.Tests/packages.config @@ -1,7 +1,7 @@  - - - + + + \ No newline at end of file diff --git a/src/csharp/Grpc.Reflection.Tests/project.json b/src/csharp/Grpc.Reflection.Tests/project.json index b90834a25eb..fc05557c884 100644 --- a/src/csharp/Grpc.Reflection.Tests/project.json +++ b/src/csharp/Grpc.Reflection.Tests/project.json @@ -45,8 +45,8 @@ "Grpc.Reflection": { "target": "project" }, - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index 4e254a0b539..b0ab170e3f8 100644 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -36,12 +36,12 @@ - - ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + ..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll + diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs index 06c5d08030d..86e9aace8c8 100644 --- a/src/csharp/Grpc.Reflection/Reflection.cs +++ b/src/csharp/Grpc.Reflection/Reflection.cs @@ -70,7 +70,7 @@ namespace Grpc.Reflection.V1Alpha { } #region Messages /// - /// The message sent by the client when calling ServerReflectionInfo method. + /// The message sent by the client when calling ServerReflectionInfo method. /// public sealed partial class ServerReflectionRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServerReflectionRequest()); @@ -136,7 +136,7 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "file_by_filename" field. public const int FileByFilenameFieldNumber = 3; /// - /// Find a proto file by the file name. + /// Find a proto file by the file name. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string FileByFilename { @@ -150,9 +150,9 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "file_containing_symbol" field. public const int FileContainingSymbolFieldNumber = 4; /// - /// Find the proto file that declares the given fully-qualified symbol name. - /// This field should be a fully-qualified symbol name - /// (e.g. <package>.<service>[.<method>] or <package>.<type>). + /// Find the proto file that declares the given fully-qualified symbol name. + /// This field should be a fully-qualified symbol name + /// (e.g. <package>.<service>[.<method>] or <package>.<type>). /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string FileContainingSymbol { @@ -166,8 +166,8 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "file_containing_extension" field. public const int FileContainingExtensionFieldNumber = 5; /// - /// Find the proto file which defines an extension extending the given - /// message type with the given field number. + /// Find the proto file which defines an extension extending the given + /// message type with the given field number. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Reflection.V1Alpha.ExtensionRequest FileContainingExtension { @@ -181,14 +181,14 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "all_extension_numbers_of_type" field. public const int AllExtensionNumbersOfTypeFieldNumber = 6; /// - /// Finds the tag numbers used by all known extensions of the given message - /// type, and appends them to ExtensionNumberResponse in an undefined order. - /// Its corresponding method is best-effort: it's not guaranteed that the - /// reflection service will implement this method, and it's not guaranteed - /// that this method will provide all extensions. Returns - /// StatusCode::UNIMPLEMENTED if it's not implemented. - /// This field should be a fully-qualified type name. The format is - /// <package>.<type> + /// Finds the tag numbers used by all known extensions of the given message + /// type, and appends them to ExtensionNumberResponse in an undefined order. + /// Its corresponding method is best-effort: it's not guaranteed that the + /// reflection service will implement this method, and it's not guaranteed + /// that this method will provide all extensions. Returns + /// StatusCode::UNIMPLEMENTED if it's not implemented. + /// This field should be a fully-qualified type name. The format is + /// <package>.<type> /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string AllExtensionNumbersOfType { @@ -202,8 +202,8 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "list_services" field. public const int ListServicesFieldNumber = 7; /// - /// List the full names of registered services. The content will not be - /// checked. + /// List the full names of registered services. The content will not be + /// checked. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string ListServices { @@ -401,8 +401,8 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// The type name and extension number sent by the client when requesting - /// file_containing_extension. + /// The type name and extension number sent by the client when requesting + /// file_containing_extension. /// public sealed partial class ExtensionRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExtensionRequest()); @@ -441,7 +441,7 @@ namespace Grpc.Reflection.V1Alpha { public const int ContainingTypeFieldNumber = 1; private string containingType_ = ""; /// - /// Fully-qualified type name. The format should be <package>.<type> + /// Fully-qualified type name. The format should be <package>.<type> /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string ContainingType { @@ -553,7 +553,7 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// The message sent by the server to answer ServerReflectionInfo method. + /// The message sent by the server to answer ServerReflectionInfo method. /// public sealed partial class ServerReflectionResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServerReflectionResponse()); @@ -628,12 +628,12 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "file_descriptor_response" field. public const int FileDescriptorResponseFieldNumber = 4; /// - /// This message is used to answer file_by_filename, file_containing_symbol, - /// file_containing_extension requests with transitive dependencies. As - /// the repeated label is not allowed in oneof fields, we use a - /// FileDescriptorResponse message to encapsulate the repeated fields. - /// The reflection service is allowed to avoid sending FileDescriptorProtos - /// that were previously sent in response to earlier requests in the stream. + /// This message is used to answer file_by_filename, file_containing_symbol, + /// file_containing_extension requests with transitive dependencies. As + /// the repeated label is not allowed in oneof fields, we use a + /// FileDescriptorResponse message to encapsulate the repeated fields. + /// The reflection service is allowed to avoid sending FileDescriptorProtos + /// that were previously sent in response to earlier requests in the stream. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Reflection.V1Alpha.FileDescriptorResponse FileDescriptorResponse { @@ -647,7 +647,7 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "all_extension_numbers_response" field. public const int AllExtensionNumbersResponseFieldNumber = 5; /// - /// This message is used to answer all_extension_numbers_of_type requst. + /// This message is used to answer all_extension_numbers_of_type requst. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse AllExtensionNumbersResponse { @@ -661,7 +661,7 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "list_services_response" field. public const int ListServicesResponseFieldNumber = 6; /// - /// This message is used to answer list_services request. + /// This message is used to answer list_services request. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Reflection.V1Alpha.ListServiceResponse ListServicesResponse { @@ -675,7 +675,7 @@ namespace Grpc.Reflection.V1Alpha { /// Field number for the "error_response" field. public const int ErrorResponseFieldNumber = 7; /// - /// This message is used when an error occurs. + /// This message is used when an error occurs. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Reflection.V1Alpha.ErrorResponse ErrorResponse { @@ -893,9 +893,9 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// Serialized FileDescriptorProto messages sent by the server answering - /// a file_by_filename, file_containing_symbol, or file_containing_extension - /// request. + /// Serialized FileDescriptorProto messages sent by the server answering + /// a file_by_filename, file_containing_symbol, or file_containing_extension + /// request. /// public sealed partial class FileDescriptorResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileDescriptorResponse()); @@ -935,9 +935,9 @@ namespace Grpc.Reflection.V1Alpha { = pb::FieldCodec.ForBytes(10); private readonly pbc::RepeatedField fileDescriptorProto_ = new pbc::RepeatedField(); /// - /// Serialized FileDescriptorProto messages. We avoid taking a dependency on - /// descriptor.proto, which uses proto2 only features, by making them opaque - /// bytes instead. + /// Serialized FileDescriptorProto messages. We avoid taking a dependency on + /// descriptor.proto, which uses proto2 only features, by making them opaque + /// bytes instead. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField FileDescriptorProto { @@ -1012,8 +1012,8 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// A list of extension numbers sent by the server answering - /// all_extension_numbers_of_type request. + /// A list of extension numbers sent by the server answering + /// all_extension_numbers_of_type request. /// public sealed partial class ExtensionNumberResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExtensionNumberResponse()); @@ -1052,8 +1052,8 @@ namespace Grpc.Reflection.V1Alpha { public const int BaseTypeNameFieldNumber = 1; private string baseTypeName_ = ""; /// - /// Full name of the base type, including the package name. The format - /// is <package>.<type> + /// Full name of the base type, including the package name. The format + /// is <package>.<type> /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string BaseTypeName { @@ -1158,7 +1158,7 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// A list of ServiceResponse sent by the server answering list_services request. + /// A list of ServiceResponse sent by the server answering list_services request. /// public sealed partial class ListServiceResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ListServiceResponse()); @@ -1198,8 +1198,8 @@ namespace Grpc.Reflection.V1Alpha { = pb::FieldCodec.ForMessage(10, global::Grpc.Reflection.V1Alpha.ServiceResponse.Parser); private readonly pbc::RepeatedField service_ = new pbc::RepeatedField(); /// - /// The information of each service may be expanded in the future, so we use - /// ServiceResponse message to encapsulate it. + /// The information of each service may be expanded in the future, so we use + /// ServiceResponse message to encapsulate it. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField Service { @@ -1274,8 +1274,8 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// The information of a single service used by ListServiceResponse to answer - /// list_services request. + /// The information of a single service used by ListServiceResponse to answer + /// list_services request. /// public sealed partial class ServiceResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServiceResponse()); @@ -1313,8 +1313,8 @@ namespace Grpc.Reflection.V1Alpha { public const int NameFieldNumber = 1; private string name_ = ""; /// - /// Full name of a registered service, including its package name. The format - /// is <package>.<service> + /// Full name of a registered service, including its package name. The format + /// is <package>.<service> /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { @@ -1399,7 +1399,7 @@ namespace Grpc.Reflection.V1Alpha { } /// - /// The error code and error message sent by the server when an error occurs. + /// The error code and error message sent by the server when an error occurs. /// public sealed partial class ErrorResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ErrorResponse()); @@ -1438,7 +1438,7 @@ namespace Grpc.Reflection.V1Alpha { public const int ErrorCodeFieldNumber = 1; private int errorCode_; /// - /// This field uses the error codes defined in grpc::StatusCode. + /// This field uses the error codes defined in grpc::StatusCode. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ErrorCode { diff --git a/src/csharp/Grpc.Reflection/packages.config b/src/csharp/Grpc.Reflection/packages.config index 5ab40b7a8ce..eec292b306d 100644 --- a/src/csharp/Grpc.Reflection/packages.config +++ b/src/csharp/Grpc.Reflection/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Reflection/project.json b/src/csharp/Grpc.Reflection/project.json index bfc57661eb3..8bfe722f780 100644 --- a/src/csharp/Grpc.Reflection/project.json +++ b/src/csharp/Grpc.Reflection/project.json @@ -22,15 +22,10 @@ }, "dependencies": { "Grpc.Core": "1.2.0-dev", - "Google.Protobuf": "3.0.0" + "Google.Protobuf": "3.2.0" }, "frameworks": { - "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } - }, + "net45": {}, "netstandard1.5": { "dependencies": { "NETStandard.Library": "1.6.0" diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 6a241190b27..491df4de6ad 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -1023,6 +1023,31 @@ GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_cr return grpc_metadata_credentials_create_from_plugin(plugin, NULL); } +/* Auth context */ + +GPR_EXPORT grpc_auth_context *GPR_CALLTYPE grpcsharp_call_auth_context(grpc_call *call) { + return grpc_call_auth_context(call); +} + +GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_auth_context_peer_identity_property_name( + const grpc_auth_context *ctx) { + return grpc_auth_context_peer_identity_property_name(ctx); +} + +GPR_EXPORT grpc_auth_property_iterator GPR_CALLTYPE +grpcsharp_auth_context_property_iterator(const grpc_auth_context *ctx) { + return grpc_auth_context_property_iterator(ctx); +} + +GPR_EXPORT const grpc_auth_property *GPR_CALLTYPE grpcsharp_auth_property_iterator_next( + grpc_auth_property_iterator *it) { + return grpc_auth_property_iterator_next(it); +} + +GPR_EXPORT void GPR_CALLTYPE grpcsharp_auth_context_release(grpc_auth_context *ctx) { + grpc_auth_context_release(ctx); +} + /* Logging */ typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, int32_t line, diff --git a/src/csharp/global.json b/src/csharp/global.json new file mode 100644 index 00000000000..32ff399ef94 --- /dev/null +++ b/src/csharp/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "1.0.0-preview2-003121" + } +} \ No newline at end of file diff --git a/src/csharp/tests.json b/src/csharp/tests.json index 4ce6769eee5..707d140f62c 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -8,6 +8,8 @@ "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest", "Grpc.Core.Internal.Tests.TimespecTest", "Grpc.Core.Tests.AppDomainUnloadTest", + "Grpc.Core.Tests.AuthContextTest", + "Grpc.Core.Tests.AuthPropertyTest", "Grpc.Core.Tests.CallCredentialsTest", "Grpc.Core.Tests.CallOptionsTest", "Grpc.Core.Tests.ChannelCredentialsTest", @@ -20,7 +22,6 @@ "Grpc.Core.Tests.HalfcloseTest", "Grpc.Core.Tests.MarshallingErrorsTest", "Grpc.Core.Tests.MetadataTest", - "Grpc.Core.Tests.NUnitVersionTest", "Grpc.Core.Tests.PerformanceTest", "Grpc.Core.Tests.PInvokeTest", "Grpc.Core.Tests.ResponseHeadersTest", diff --git a/src/php/README.md b/src/php/README.md index 821ea16aab6..f08541f16cf 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -158,7 +158,7 @@ $ composer install ### Protobuf compiler Again if you don't have it already, you need to install the protobuf compiler -`protoc`, version 3.2.0+. +`protoc`, version 3.1.0+ (the newer the better). If `protoc` hasn't been installed, you can download the `protoc` binaries from [the protocol buffers Github repository](https://github.com/google/protobuf/releases). diff --git a/src/php/composer.json b/src/php/composer.json index 8528304c81f..491e34795ac 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -5,7 +5,7 @@ "version": "1.2.0", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index b64a708cc78..a4481b2ac35 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1004,7 +1004,7 @@ def unary_unary_rpc_method_handler(behavior, An RpcMethodHandler for a unary-unary RPC method constructed from the given parameters. """ - from grpc import _utilities + from grpc import _utilities # pylint: disable=cyclic-import return _utilities.RpcMethodHandler(False, False, request_deserializer, response_serializer, behavior, None, None, None) @@ -1025,7 +1025,7 @@ def unary_stream_rpc_method_handler(behavior, An RpcMethodHandler for a unary-stream RPC method constructed from the given parameters. """ - from grpc import _utilities + from grpc import _utilities # pylint: disable=cyclic-import return _utilities.RpcMethodHandler(False, True, request_deserializer, response_serializer, None, behavior, None, None) @@ -1046,7 +1046,7 @@ def stream_unary_rpc_method_handler(behavior, An RpcMethodHandler for a stream-unary RPC method constructed from the given parameters. """ - from grpc import _utilities + from grpc import _utilities # pylint: disable=cyclic-import return _utilities.RpcMethodHandler(True, False, request_deserializer, response_serializer, None, None, behavior, None) @@ -1068,7 +1068,7 @@ def stream_stream_rpc_method_handler(behavior, An RpcMethodHandler for a stream-stream RPC method constructed from the given parameters. """ - from grpc import _utilities + from grpc import _utilities # pylint: disable=cyclic-import return _utilities.RpcMethodHandler(True, True, request_deserializer, response_serializer, None, None, None, behavior) @@ -1085,7 +1085,7 @@ def method_handlers_generic_handler(service, method_handlers): Returns: A GenericRpcHandler constructed from the given parameters. """ - from grpc import _utilities + from grpc import _utilities # pylint: disable=cyclic-import return _utilities.DictionaryGenericHandler(service, method_handlers) @@ -1124,7 +1124,7 @@ def metadata_call_credentials(metadata_plugin, name=None): Returns: A CallCredentials. """ - from grpc import _plugin_wrapping + from grpc import _plugin_wrapping # pylint: disable=cyclic-import if name is None: try: effective_name = metadata_plugin.__name__ @@ -1147,7 +1147,7 @@ def access_token_call_credentials(access_token): Returns: A CallCredentials. """ - from grpc import _auth + from grpc import _auth # pylint: disable=cyclic-import return metadata_call_credentials( _auth.AccessTokenCallCredentials(access_token)) @@ -1161,7 +1161,7 @@ def composite_call_credentials(*call_credentials): Returns: A CallCredentials object composed of the given CallCredentials objects. """ - from grpc import _credential_composition + from grpc import _credential_composition # pylint: disable=cyclic-import cygrpc_call_credentials = tuple( single_call_credentials._credentials for single_call_credentials in call_credentials) @@ -1180,7 +1180,7 @@ def composite_channel_credentials(channel_credentials, *call_credentials): A ChannelCredentials composed of the given ChannelCredentials and CallCredentials objects. """ - from grpc import _credential_composition + from grpc import _credential_composition # pylint: disable=cyclic-import cygrpc_call_credentials = tuple( single_call_credentials._credentials for single_call_credentials in call_credentials) @@ -1237,7 +1237,7 @@ def channel_ready_future(channel): A Future that matures when the given Channel has connectivity ChannelConnectivity.READY. """ - from grpc import _utilities + from grpc import _utilities # pylint: disable=cyclic-import return _utilities.channel_ready_future(channel) @@ -1252,7 +1252,7 @@ def insecure_channel(target, options=None): Returns: A Channel to the target through which RPCs may be conducted. """ - from grpc import _channel + from grpc import _channel # pylint: disable=cyclic-import return _channel.Channel(target, () if options is None else options, None) @@ -1268,7 +1268,7 @@ def secure_channel(target, credentials, options=None): Returns: A Channel to the target through which RPCs may be conducted. """ - from grpc import _channel + from grpc import _channel # pylint: disable=cyclic-import return _channel.Channel(target, () if options is None else options, credentials._credentials) @@ -1290,7 +1290,7 @@ def server(thread_pool, handlers=None, options=None): Returns: A Server with which RPCs can be serviced. """ - from grpc import _server + from grpc import _server # pylint: disable=cyclic-import return _server.Server(thread_pool, () if handlers is None else handlers, () if options is None else options) diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py index 21131f85f17..cb7c6fe4fda 100644 --- a/src/python/grpcio/grpc/_auth.py +++ b/src/python/grpcio/grpc/_auth.py @@ -39,6 +39,19 @@ def _sign_request(callback, token, error): callback(metadata, error) +def _create_get_token_callback(callback): + + def get_token_callback(future): + try: + access_token = future.result().access_token + except Exception as exception: # pylint: disable=broad-except + _sign_request(callback, None, exception) + else: + _sign_request(callback, access_token, None) + + return get_token_callback + + class GoogleCallCredentials(grpc.AuthMetadataPlugin): """Metadata wrapper for GoogleCredentials from the oauth2client library.""" @@ -59,16 +72,7 @@ class GoogleCallCredentials(grpc.AuthMetadataPlugin): additional_claims={'aud': context.service_url}) else: future = self._pool.submit(self._credentials.get_access_token) - future.add_done_callback( - lambda x: self._get_token_callback(callback, x)) - - def _get_token_callback(self, callback, future): - try: - access_token = future.result().access_token - except Exception as e: - _sign_request(callback, None, e) - else: - _sign_request(callback, access_token, None) + future.add_done_callback(_create_get_token_callback(callback)) def __del__(self): self._pool.shutdown(wait=False) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index af86f5eabe3..4316449ac65 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -200,7 +200,7 @@ def _consume_request_iterator(request_iterator, state, call, request = next(request_iterator) except StopIteration: break - except Exception as e: + except Exception: # pylint: disable=broad-except logging.exception("Exception iterating requests!") call.cancel() _abort(state, grpc.StatusCode.UNKNOWN, @@ -237,7 +237,7 @@ def _consume_request_iterator(request_iterator, state, call, cygrpc.Operations(operations), event_handler) state.due.add(cygrpc.OperationType.send_close_from_client) - def stop_consumption_thread(timeout): + def stop_consumption_thread(timeout): # pylint: disable=unused-argument with state.condition: if state.code is None: call.cancel() @@ -387,13 +387,14 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): with self._state.condition: while self._state.initial_metadata is None: self._state.condition.wait() - return _common.application_metadata(self._state.initial_metadata) + return _common.to_application_metadata(self._state.initial_metadata) def trailing_metadata(self): with self._state.condition: while self._state.trailing_metadata is None: self._state.condition.wait() - return _common.application_metadata(self._state.trailing_metadata) + return _common.to_application_metadata( + self._state.trailing_metadata) def code(self): with self._state.condition: @@ -473,7 +474,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None) operations = ( cygrpc.operation_send_initial_metadata( - _common.cygrpc_metadata(metadata), _EMPTY_FLAGS), + _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS), cygrpc.operation_send_close_from_client(_EMPTY_FLAGS), cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS), @@ -563,7 +564,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): )), event_handler) operations = ( cygrpc.operation_send_initial_metadata( - _common.cygrpc_metadata(metadata), + _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), cygrpc.operation_send_message( serialized_request, _EMPTY_FLAGS), cygrpc.operation_send_close_from_client(_EMPTY_FLAGS), @@ -603,7 +604,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): None) operations = ( cygrpc.operation_send_initial_metadata( - _common.cygrpc_metadata(metadata), _EMPTY_FLAGS), + _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), cygrpc.operation_receive_message(_EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) call_error = call.start_client_batch( @@ -657,7 +658,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): event_handler) operations = ( cygrpc.operation_send_initial_metadata( - _common.cygrpc_metadata(metadata), _EMPTY_FLAGS), + _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), cygrpc.operation_receive_message(_EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) call_error = call.start_client_batch( @@ -700,7 +701,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): event_handler) operations = ( cygrpc.operation_send_initial_metadata( - _common.cygrpc_metadata(metadata), _EMPTY_FLAGS), + _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) call_error = call.start_client_batch( cygrpc.Operations(operations), event_handler) @@ -735,7 +736,7 @@ def _run_channel_spin_thread(state): state.managed_calls = None return - def stop_channel_spin(timeout): + def stop_channel_spin(timeout): # pylint: disable=unused-argument with state.lock: if state.managed_calls is not None: for call in state.managed_calls: @@ -876,12 +877,8 @@ def _moot(state): def _subscribe(state, callback, try_to_connect): with state.lock: if not state.callbacks_and_connectivities and not state.polling: - - def cancel_all_subscriptions(timeout): - _moot(state) - polling_thread = _common.CleanupThread( - cancel_all_subscriptions, + lambda timeout: _moot(state), target=_poll_connectivity, args=(state, state.channel, bool(try_to_connect))) polling_thread.start() diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py index 6879e1780ba..2e369013f5f 100644 --- a/src/python/grpcio/grpc/_common.py +++ b/src/python/grpcio/grpc/_common.py @@ -97,22 +97,22 @@ def decode(b): def channel_args(options): - channel_args = [] + cygrpc_args = [] for key, value in options: if isinstance(value, six.string_types): - channel_args.append(cygrpc.ChannelArg(encode(key), encode(value))) + cygrpc_args.append(cygrpc.ChannelArg(encode(key), encode(value))) else: - channel_args.append(cygrpc.ChannelArg(encode(key), value)) - return cygrpc.ChannelArgs(channel_args) + cygrpc_args.append(cygrpc.ChannelArg(encode(key), value)) + return cygrpc.ChannelArgs(cygrpc_args) -def cygrpc_metadata(application_metadata): +def to_cygrpc_metadata(application_metadata): return EMPTY_METADATA if application_metadata is None else cygrpc.Metadata( cygrpc.Metadatum(encode(key), encode(value)) for key, value in application_metadata) -def application_metadata(cygrpc_metadata): +def to_application_metadata(cygrpc_metadata): if cygrpc_metadata is None: return () else: diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py index 69c46aa546c..1e44561c97b 100644 --- a/src/python/grpcio/grpc/_plugin_wrapping.py +++ b/src/python/grpcio/grpc/_plugin_wrapping.py @@ -66,9 +66,9 @@ class _WrappedCygrpcCallback(object): def _invoke_success(self, metadata): try: - cygrpc_metadata = _common.cygrpc_metadata(metadata) - except Exception as error: - self._invoke_failure(error) + cygrpc_metadata = _common.to_cygrpc_metadata(metadata) + except Exception as exception: # pylint: disable=broad-except + self._invoke_failure(exception) return self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'') diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index b8e7ea17f70..84e096d4c04 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -142,14 +142,14 @@ def _abort(state, call, code, details): effective_details = details if state.details is None else state.details if state.initial_metadata_allowed: operations = (cygrpc.operation_send_initial_metadata( - _common.EMPTY_METADATA, _EMPTY_FLAGS), - cygrpc.operation_send_status_from_server( - _common.cygrpc_metadata(state.trailing_metadata), - effective_code, effective_details, _EMPTY_FLAGS),) + _common.EMPTY_METADATA, + _EMPTY_FLAGS), cygrpc.operation_send_status_from_server( + _common.to_cygrpc_metadata(state.trailing_metadata), + effective_code, effective_details, _EMPTY_FLAGS),) token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN else: operations = (cygrpc.operation_send_status_from_server( - _common.cygrpc_metadata(state.trailing_metadata), + _common.to_cygrpc_metadata(state.trailing_metadata), effective_code, effective_details, _EMPTY_FLAGS),) token = _SEND_STATUS_FROM_SERVER_TOKEN call.start_server_batch( @@ -250,7 +250,7 @@ class _Context(grpc.ServicerContext): self._state.disable_next_compression = True def invocation_metadata(self): - return _common.application_metadata(self._rpc_event.request_metadata) + return _common.to_application_metadata(self._rpc_event.request_metadata) def peer(self): return _common.decode(self._rpc_event.operation_call.peer()) @@ -262,7 +262,8 @@ class _Context(grpc.ServicerContext): else: if self._state.initial_metadata_allowed: operation = cygrpc.operation_send_initial_metadata( - _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS) + _common.to_cygrpc_metadata(initial_metadata), + _EMPTY_FLAGS) self._rpc_event.operation_call.start_server_batch( cygrpc.Operations((operation,)), _send_initial_metadata(self._state)) @@ -273,7 +274,7 @@ class _Context(grpc.ServicerContext): def set_trailing_metadata(self, trailing_metadata): with self._state.condition: - self._state.trailing_metadata = _common.cygrpc_metadata( + self._state.trailing_metadata = _common.to_cygrpc_metadata( trailing_metadata) def set_code(self, code): @@ -342,7 +343,7 @@ def _unary_request(rpc_event, state, request_deserializer): if state.client is _CANCELLED or state.statused: return None else: - start_server_batch_result = rpc_event.operation_call.start_server_batch( + rpc_event.operation_call.start_server_batch( cygrpc.Operations( (cygrpc.operation_receive_message(_EMPTY_FLAGS),)), _receive_message(state, rpc_event.operation_call, @@ -436,7 +437,8 @@ def _send_response(rpc_event, state, serialized_response): def _status(rpc_event, state, serialized_response): with state.condition: if state.client is not _CANCELLED: - trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata) + trailing_metadata = _common.to_cygrpc_metadata( + state.trailing_metadata) code = _completion_code(state) details = _details(state) operations = [ diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py index b53395e2a2e..3c69acc0195 100644 --- a/src/python/grpcio/grpc/beta/_client_adaptations.py +++ b/src/python/grpcio/grpc/beta/_client_adaptations.py @@ -30,12 +30,13 @@ import grpc from grpc import _common -from grpc._cython import cygrpc from grpc.beta import interfaces from grpc.framework.common import cardinality from grpc.framework.foundation import future from grpc.framework.interfaces.face import face +# pylint: disable=too-many-arguments,too-many-locals,unused-argument + _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = { grpc.StatusCode.CANCELLED: (face.Abortion.Kind.CANCELLED, face.CancellationError), @@ -621,8 +622,8 @@ class _GenericStub(face.GenericStub): class _DynamicStub(face.DynamicStub): - def __init__(self, generic_stub, group, cardinalities): - self._generic_stub = generic_stub + def __init__(self, backing_generic_stub, group, cardinalities): + self._generic_stub = backing_generic_stub self._group = group self._cardinalities = cardinalities diff --git a/src/python/grpcio/grpc/beta/_connectivity_channel.py b/src/python/grpcio/grpc/beta/_connectivity_channel.py deleted file mode 100644 index bfb847f80af..00000000000 --- a/src/python/grpcio/grpc/beta/_connectivity_channel.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Affords a connectivity-state-listenable channel.""" - -import threading -import time - -from grpc._adapter import _low -from grpc._adapter import _types -from grpc.beta import interfaces -from grpc.framework.foundation import callable_util - -_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = ( - 'Exception calling channel subscription callback!') - -_LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = { - state: connectivity - for state, connectivity in zip(_types.ConnectivityState, - interfaces.ChannelConnectivity) -} - - -class ConnectivityChannel(object): - - def __init__(self, low_channel): - self._lock = threading.Lock() - self._low_channel = low_channel - - self._polling = False - self._connectivity = None - self._try_to_connect = False - self._callbacks_and_connectivities = [] - self._delivering = False - - def _deliveries(self, connectivity): - callbacks_needing_update = [] - for callback_and_connectivity in self._callbacks_and_connectivities: - callback, callback_connectivity = callback_and_connectivity - if callback_connectivity is not connectivity: - callbacks_needing_update.append(callback) - callback_and_connectivity[1] = connectivity - return callbacks_needing_update - - def _deliver(self, initial_connectivity, initial_callbacks): - connectivity = initial_connectivity - callbacks = initial_callbacks - while True: - for callback in callbacks: - callable_util.call_logging_exceptions( - callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE, - connectivity) - with self._lock: - callbacks = self._deliveries(self._connectivity) - if callbacks: - connectivity = self._connectivity - else: - self._delivering = False - return - - def _spawn_delivery(self, connectivity, callbacks): - delivering_thread = threading.Thread( - target=self._deliver, args=(connectivity, callbacks,)) - delivering_thread.start() - self._delivering = True - - # TODO(issue 3064): Don't poll. - def _poll_connectivity(self, low_channel, initial_try_to_connect): - try_to_connect = initial_try_to_connect - low_connectivity = low_channel.check_connectivity_state(try_to_connect) - with self._lock: - self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[ - low_connectivity] - callbacks = tuple( - callback - for callback, unused_but_known_to_be_none_connectivity in - self._callbacks_and_connectivities) - for callback_and_connectivity in self._callbacks_and_connectivities: - callback_and_connectivity[1] = self._connectivity - if callbacks: - self._spawn_delivery(self._connectivity, callbacks) - completion_queue = _low.CompletionQueue() - while True: - low_channel.watch_connectivity_state(low_connectivity, - time.time() + 0.2, - completion_queue, None) - event = completion_queue.next() - with self._lock: - if not self._callbacks_and_connectivities and not self._try_to_connect: - self._polling = False - self._connectivity = None - completion_queue.shutdown() - break - try_to_connect = self._try_to_connect - self._try_to_connect = False - if event.success or try_to_connect: - low_connectivity = low_channel.check_connectivity_state( - try_to_connect) - with self._lock: - self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[ - low_connectivity] - if not self._delivering: - callbacks = self._deliveries(self._connectivity) - if callbacks: - self._spawn_delivery(self._connectivity, callbacks) - - def subscribe(self, callback, try_to_connect): - with self._lock: - if not self._callbacks_and_connectivities and not self._polling: - polling_thread = threading.Thread( - target=self._poll_connectivity, - args=(self._low_channel, bool(try_to_connect))) - polling_thread.start() - self._polling = True - self._callbacks_and_connectivities.append([callback, None]) - elif not self._delivering and self._connectivity is not None: - self._spawn_delivery(self._connectivity, (callback,)) - self._try_to_connect |= bool(try_to_connect) - self._callbacks_and_connectivities.append( - [callback, self._connectivity]) - else: - self._try_to_connect |= bool(try_to_connect) - self._callbacks_and_connectivities.append([callback, None]) - - def unsubscribe(self, callback): - with self._lock: - for index, (subscribed_callback, unused_connectivity - ) in enumerate(self._callbacks_and_connectivities): - if callback == subscribed_callback: - self._callbacks_and_connectivities.pop(index) - break - - def low_channel(self): - return self._low_channel diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py index 174af2d6422..cf10c26d2fe 100644 --- a/src/python/grpcio/grpc/beta/_server_adaptations.py +++ b/src/python/grpcio/grpc/beta/_server_adaptations.py @@ -41,6 +41,8 @@ from grpc.framework.foundation import logging_pool from grpc.framework.foundation import stream from grpc.framework.interfaces.face import face +# pylint: disable=too-many-return-statements + _DEFAULT_POOL_SIZE = 8 @@ -78,7 +80,7 @@ class _FaceServicerContext(face.ServicerContext): return _ServerProtocolContext(self._servicer_context) def invocation_metadata(self): - return _common.cygrpc_metadata( + return _common.to_cygrpc_metadata( self._servicer_context.invocation_metadata()) def initial_metadata(self, initial_metadata): @@ -179,7 +181,7 @@ def _run_request_pipe_thread(request_iterator, request_consumer, return request_consumer.terminate() - def stop_request_pipe(timeout): + def stop_request_pipe(timeout): # pylint: disable=unused-argument thread_joined.set() request_pipe_thread = _common.CleanupThread( @@ -351,27 +353,27 @@ class _GenericRpcHandler(grpc.GenericRpcHandler): class _Server(interfaces.Server): - def __init__(self, server): - self._server = server + def __init__(self, grpc_server): + self._grpc_server = grpc_server def add_insecure_port(self, address): - return self._server.add_insecure_port(address) + return self._grpc_server.add_insecure_port(address) def add_secure_port(self, address, server_credentials): - return self._server.add_secure_port(address, server_credentials) + return self._grpc_server.add_secure_port(address, server_credentials) def start(self): - self._server.start() + self._grpc_server.start() def stop(self, grace): - return self._server.stop(grace) + return self._grpc_server.stop(grace) def __enter__(self): - self._server.start() + self._grpc_server.start() return self def __exit__(self, exc_type, exc_val, exc_tb): - self._server.stop(None) + self._grpc_server.stop(None) return False diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py index 70938522781..113fd38f8a6 100644 --- a/src/python/grpcio/grpc/beta/implementations.py +++ b/src/python/grpcio/grpc/beta/implementations.py @@ -29,19 +29,20 @@ """Entry points into the Beta API of gRPC Python.""" # threading is referenced from specification in this module. -import abc -import enum import threading # pylint: disable=unused-import -# cardinality and face are referenced from specification in this module. +# interfaces, cardinality, and face are referenced from specification in this +# module. import grpc from grpc import _auth from grpc.beta import _client_adaptations from grpc.beta import _server_adaptations -from grpc.beta import interfaces +from grpc.beta import interfaces # pylint: disable=unused-import from grpc.framework.common import cardinality # pylint: disable=unused-import from grpc.framework.interfaces.face import face # pylint: disable=unused-import +# pylint: disable=too-many-arguments + ChannelCredentials = grpc.ChannelCredentials ssl_channel_credentials = grpc.ssl_channel_credentials CallCredentials = grpc.CallCredentials @@ -218,7 +219,7 @@ def dynamic_stub(channel, service, cardinalities, options=None): Returns: A face.DynamicStub with which RPCs can be invoked. """ - effective_options = StubOptions() if options is None else options + effective_options = _EMPTY_STUB_OPTIONS if options is None else options return _client_adaptations.dynamic_stub( channel._channel, # pylint: disable=protected-access service, diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py index 7ee37373fa1..0912fba1394 100644 --- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py +++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py @@ -39,7 +39,7 @@ def _wrap(behavior): def _wrapping(*args, **kwargs): try: return behavior(*args, **kwargs) - except Exception as e: + except Exception: logging.exception( 'Unexpected exception from %s executed in logging pool!', behavior) diff --git a/src/python/grpcio/grpc/framework/interfaces/base/base.py b/src/python/grpcio/grpc/framework/interfaces/base/base.py index cb3328296c5..aa80e65f57a 100644 --- a/src/python/grpcio/grpc/framework/interfaces/base/base.py +++ b/src/python/grpcio/grpc/framework/interfaces/base/base.py @@ -46,26 +46,29 @@ import six # abandonment is referenced from specification in this module. from grpc.framework.foundation import abandonment # pylint: disable=unused-import +# pylint: disable=too-many-arguments + class NoSuchMethodError(Exception): """Indicates that an unrecognized operation has been called. - Attributes: - code: A code value to communicate to the other side of the operation along - with indication of operation termination. May be None. - details: A details value to communicate to the other side of the operation - along with indication of operation termination. May be None. - """ - - def __init__(self, code, details): - """Constructor. - - Args: + Attributes: code: A code value to communicate to the other side of the operation along with indication of operation termination. May be None. details: A details value to communicate to the other side of the operation along with indication of operation termination. May be None. """ + + def __init__(self, code, details): + """Constructor. + + Args: + code: A code value to communicate to the other side of the operation + along with indication of operation termination. May be None. + details: A details value to communicate to the other side of the + operation along with indication of operation termination. May be None. + """ + super(NoSuchMethodError, self).__init__() self.code = code self.details = details diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py index 6c7e2a3af6a..c6c44fe4e4c 100644 --- a/src/python/grpcio/grpc/framework/interfaces/face/face.py +++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py @@ -42,6 +42,8 @@ from grpc.framework.foundation import abandonment # pylint: disable=unused-impo from grpc.framework.foundation import future # pylint: disable=unused-import from grpc.framework.foundation import stream # pylint: disable=unused-import +# pylint: disable=too-many-arguments + class NoSuchMethodError(Exception): """Raised by customer code to indicate an unrecognized method. diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 072c3263c6e..52ee98a2d5b 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -47,7 +47,7 @@ PACKAGE_DIRECTORIES = { SETUP_REQUIRES = ( 'grpcio-tools>={version}'.format(version=grpc_version.VERSION),) -INSTALL_REQUIRES = ('protobuf>=3.0.0', +INSTALL_REQUIRES = ('protobuf>=3.2.0', 'grpcio>={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py index 19aafe443a9..e85092db570 100644 --- a/src/python/grpcio_reflection/setup.py +++ b/src/python/grpcio_reflection/setup.py @@ -47,7 +47,7 @@ PACKAGE_DIRECTORIES = { SETUP_REQUIRES = ( 'grpcio-tools>={version}'.format(version=grpc_version.VERSION),) -INSTALL_REQUIRES = ('protobuf>=3.0.0', +INSTALL_REQUIRES = ('protobuf>=3.2.0', 'grpcio>={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index b0c73fc575b..b9f0264dae3 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -56,7 +56,7 @@ INSTALL_REQUIRES = ( 'grpcio>={version}'.format(version=grpc_version.VERSION), 'grpcio-tools>={version}'.format(version=grpc_version.VERSION), 'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION), - 'oauth2client>=1.4.7', 'protobuf>=3.0.0', 'six>=1.10',) + 'oauth2client>=1.4.7', 'protobuf>=3.2.0', 'six>=1.10',) COMMAND_CLASS = { # Run `preprocess` *before* doing any packaging! diff --git a/src/python/grpcio_tests/tests/http2/negative_http2_client.py b/src/python/grpcio_tests/tests/http2/negative_http2_client.py index b8adf093a56..b184e62cfd4 100644 --- a/src/python/grpcio_tests/tests/http2/negative_http2_client.py +++ b/src/python/grpcio_tests/tests/http2/negative_http2_client.py @@ -31,6 +31,7 @@ import argparse import grpc +import time from src.proto.grpc.testing import test_pb2 from src.proto.grpc.testing import messages_pb2 @@ -75,6 +76,7 @@ def _goaway(stub): first_response = stub.UnaryCall(_SIMPLE_REQUEST) _validate_payload_type_and_length(first_response, messages_pb2.COMPRESSABLE, _RESPONSE_SIZE) + time.sleep(1) second_response = stub.UnaryCall(_SIMPLE_REQUEST) _validate_payload_type_and_length(second_response, messages_pb2.COMPRESSABLE, _RESPONSE_SIZE) diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py index f2e3898ed6f..ee235032f07 100644 --- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py +++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py @@ -249,3 +249,7 @@ class InvocationDefectsTest(unittest.TestCase): with self.assertRaises(grpc.RpcError): for _ in range(test_constants.STREAM_LENGTH // 2 + 1): next(response_iterator) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py index be3522f46f2..eb5f4598480 100644 --- a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py +++ b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py @@ -35,8 +35,8 @@ import unittest from grpc import _common _SHORT_TIME = 0.5 -_LONG_TIME = 2.0 -_EPSILON = 0.1 +_LONG_TIME = 5.0 +_EPSILON = 0.5 def cleanup(timeout): diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index b379664bab8..ecb66239b90 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -27,6 +27,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +require 'etc' require 'mkmf' LIBDIR = RbConfig::CONFIG['libdir'] @@ -80,7 +81,9 @@ ENV['BUILDDIR'] = output_dir unless windows puts 'Building internal gRPC into ' + grpc_lib_dir - system("make -j -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config}") + nproc = 4 + nproc = Etc.nprocessors * 2 if Etc.respond_to? :nprocessors + system("make -j#{nproc} -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config}") exit 1 unless $? == 0 end diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 52465a4dd70..3ef6f0eb299 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -296,6 +296,7 @@ gpr_ref_type gpr_ref_import; gpr_ref_non_zero_type gpr_ref_non_zero_import; gpr_refn_type gpr_refn_import; gpr_unref_type gpr_unref_import; +gpr_ref_is_unique_type gpr_ref_is_unique_import; gpr_stats_init_type gpr_stats_init_import; gpr_stats_inc_type gpr_stats_inc_import; gpr_stats_read_type gpr_stats_read_import; @@ -589,6 +590,7 @@ void grpc_rb_load_imports(HMODULE library) { gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero"); gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn"); gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref"); + gpr_ref_is_unique_import = (gpr_ref_is_unique_type) GetProcAddress(library, "gpr_ref_is_unique"); gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init"); gpr_stats_inc_import = (gpr_stats_inc_type) GetProcAddress(library, "gpr_stats_inc"); gpr_stats_read_import = (gpr_stats_read_type) GetProcAddress(library, "gpr_stats_read"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index b16e6738781..ef9845dfe06 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -839,6 +839,9 @@ extern gpr_refn_type gpr_refn_import; typedef int(*gpr_unref_type)(gpr_refcount *r); extern gpr_unref_type gpr_unref_import; #define gpr_unref gpr_unref_import +typedef int(*gpr_ref_is_unique_type)(gpr_refcount *r); +extern gpr_ref_is_unique_type gpr_ref_is_unique_import; +#define gpr_ref_is_unique gpr_ref_is_unique_import typedef void(*gpr_stats_init_type)(gpr_stats_counter *c, intptr_t n); extern gpr_stats_init_type gpr_stats_init_import; #define gpr_stats_init gpr_stats_init_import diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template index 9d7034e18bc..5e401e89773 100644 --- a/templates/binding.gyp.template +++ b/templates/binding.gyp.template @@ -45,7 +45,11 @@ # out. It can be re-enabled for one build by setting the npm config # variable grpc_uv to true, and it can be re-enabled permanently by # setting it to true here. - 'grpc_uv%': 'false' + 'grpc_uv%': 'false', + # Some Node installations use the system installation of OpenSSL, and on + # some systems, the system OpenSSL still does not have ALPN support. This + # will let users recompile gRPC to work without ALPN. + 'grpc_alpn%': 'true' }, 'target_defaults': { 'include_dirs': [ @@ -56,10 +60,8 @@ 'GPR_BACKWARDS_COMPATIBILITY_MODE' ], 'conditions': [ - ['runtime=="node" and grpc_uv=="true"', { + ['grpc_uv=="true"', { 'defines': [ - # Disabling this while bugs are ironed out. Uncomment this to - # re-enable libuv integration in C core. 'GRPC_UV' ] }], @@ -77,10 +79,16 @@ 'OPENSSL_NO_ASM' ] }, { - # As of the beginning of 2017, we only support versions of Node with - # embedded versions of OpenSSL that support ALPN - 'defines': [ - 'TSI_OPENSSL_ALPN_SUPPORT=1' + 'conditions': [ + ['grpc_alpn=="true"', { + 'defines': [ + 'TSI_OPENSSL_ALPN_SUPPORT=1' + ], + }, { + 'defines': [ + 'TSI_OPENSSL_ALPN_SUPPORT=0' + ], + }] ], 'include_dirs': [ '<(node_root_dir)/deps/openssl/openssl/include', diff --git a/templates/composer.json.template b/templates/composer.json.template index f56ecb69d6d..94f0c236a96 100644 --- a/templates/composer.json.template +++ b/templates/composer.json.template @@ -9,7 +9,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index f05ee4c05f5..9ed32e31cff 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -191,7 +191,7 @@ 'test/core/util/debugger_macros.c', 'test/core/util/test_config.{c,h}', 'test/core/util/port.h', - 'test/core/util/port_posix.c', + 'test/core/util/port.c', 'test/core/util/port_server_client.{c,h}' end end diff --git a/templates/package.xml.template b/templates/package.xml.template index 80f1a1fe974..8655cfa1d94 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,7 +12,7 @@ grpc-packages@google.com yes - 2017-01-13 + 2017-03-01 ${settings.php_version.php()} @@ -24,8 +24,8 @@ BSD - - PHP Proto3 adoption #8179 - - Various bug fixes + - Added arg info macros #9751 + - Updated codegen to be consistent with protobuf #9492 @@ -312,8 +312,8 @@ - 1.1.0dev - 1.1.0dev + 1.1.0RC1 + 1.1.0RC1 beta @@ -323,7 +323,39 @@ BSD - PHP Proto3 adoption #8179 - - Various bug fixes + - Various bug fixes + + + + + 1.1.0 + 1.1.0 + + + stable + stable + + 2017-01-31 + BSD + + - PHP Proto3 adoption #8179 + - Various bug fixes + + + + + 1.2.0RC1 + 1.2.0RC1 + + + beta + beta + + 2017-03-01 + BSD + + - Added arg info macros #9751 + - Updated codegen to be consistent with protobuf #9492 diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template index 8bcac1ac740..aa233db586c 100644 --- a/templates/src/csharp/Grpc.Auth/project.json.template +++ b/templates/src/csharp/Grpc.Auth/project.json.template @@ -24,7 +24,7 @@ }, "dependencies": { "Grpc.Core": "${settings.csharp_version}", - "Google.Apis.Auth": "1.16.0" + "Google.Apis.Auth": "1.21.0" }, "frameworks": { "net45": { }, diff --git a/templates/src/csharp/Grpc.Core.Tests/project.json.template b/templates/src/csharp/Grpc.Core.Tests/project.json.template index 8a3e0755ffb..b5f8190443a 100644 --- a/templates/src/csharp/Grpc.Core.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Core.Tests/project.json.template @@ -6,10 +6,10 @@ "Grpc.Core": { "target": "project" }, - "Newtonsoft.Json": "8.0.3", - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*", - "NUnit.ConsoleRunner": "3.2.0", + "Newtonsoft.Json": "9.0.1", + "NUnit": "3.6.0", + "NUnitLite": "3.6.0", + "NUnit.ConsoleRunner": "3.6.0", "OpenCover": "4.6.519", "ReportGenerator": "2.4.4.0" }, diff --git a/templates/src/csharp/Grpc.Examples.Tests/project.json.template b/templates/src/csharp/Grpc.Examples.Tests/project.json.template index 0a9eb7c74d3..da60c017a36 100644 --- a/templates/src/csharp/Grpc.Examples.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Examples.Tests/project.json.template @@ -6,8 +6,8 @@ "Grpc.Examples": { "target": "project" }, - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { }, diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template index b8a8314de17..5de965cb1b7 100644 --- a/templates/src/csharp/Grpc.Examples/project.json.template +++ b/templates/src/csharp/Grpc.Examples/project.json.template @@ -6,15 +6,10 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0" + "Google.Protobuf": "3.2.0" }, "frameworks": { - "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } - }, + "net45": {}, "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { diff --git a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template index c63da96db75..4a993326c32 100644 --- a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template @@ -6,8 +6,8 @@ "Grpc.HealthCheck": { "target": "project" }, - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { }, diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template index cba68940153..9cd0d83a9be 100644 --- a/templates/src/csharp/Grpc.HealthCheck/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck/project.json.template @@ -24,15 +24,10 @@ }, "dependencies": { "Grpc.Core": "${settings.csharp_version}", - "Google.Protobuf": "3.0.0" + "Google.Protobuf": "3.2.0" }, "frameworks": { - "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } - }, + "net45": {}, "netstandard1.5": { "dependencies": { "NETStandard.Library": "1.6.0" diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template index 3ce94e58387..74b928110f1 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template @@ -9,18 +9,15 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0", - "CommandLineParser.Unofficial": "2.0.275", - "Moq": "4.6.38-alpha", - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "Google.Protobuf": "3.2.0", + "CommandLineParser": "2.1.1-beta", + "Moq": "4.7.0", + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } + "frameworkAssemblies": {} }, "netcoreapp1.0": { "imports": [ diff --git a/templates/src/csharp/Grpc.Reflection.Tests/project.json.template b/templates/src/csharp/Grpc.Reflection.Tests/project.json.template index 2869609138b..65d200e30b5 100644 --- a/templates/src/csharp/Grpc.Reflection.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Reflection.Tests/project.json.template @@ -6,8 +6,8 @@ "Grpc.Reflection": { "target": "project" }, - "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnit": "3.6.0", + "NUnitLite": "3.6.0" }, "frameworks": { "net45": { }, diff --git a/templates/src/csharp/Grpc.Reflection/project.json.template b/templates/src/csharp/Grpc.Reflection/project.json.template index 8a33e1ccc97..e6f65f8ab39 100644 --- a/templates/src/csharp/Grpc.Reflection/project.json.template +++ b/templates/src/csharp/Grpc.Reflection/project.json.template @@ -24,15 +24,10 @@ }, "dependencies": { "Grpc.Core": "${settings.csharp_version}", - "Google.Protobuf": "3.0.0" + "Google.Protobuf": "3.2.0" }, "frameworks": { - "net45": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.IO": "" - } - }, + "net45": {}, "netstandard1.5": { "dependencies": { "NETStandard.Library": "1.6.0" diff --git a/templates/src/php/composer.json.template b/templates/src/php/composer.json.template index ecc516d1c4b..1887ee3c822 100644 --- a/templates/src/php/composer.json.template +++ b/templates/src/php/composer.json.template @@ -7,7 +7,7 @@ "version": "${settings.php_version.php_composer()}", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/templates/tools/dockerfile/apt_get_pyenv.include b/templates/tools/dockerfile/apt_get_pyenv.include index 816b27904f6..ef0964e5975 100644 --- a/templates/tools/dockerfile/apt_get_pyenv.include +++ b/templates/tools/dockerfile/apt_get_pyenv.include @@ -12,6 +12,9 @@ RUN apt-get update && apt-get install -y ${'\\'} # Install Pyenv and dev Python versions 3.5 and 3.6 RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash +ENV PATH /root/.pyenv/bin:$PATH +RUN eval "$(pyenv init -)" +RUN eval "$(pyenv virtualenv-init -)" RUN pyenv update RUN pyenv install 3.5-dev RUN pyenv install 3.6-dev diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include index 430f3fa3f22..058ce15fb52 100644 --- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include +++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include @@ -1,7 +1,11 @@ # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 -RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.0-preview2-003121 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.1 +RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 +RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache diff --git a/templates/tools/dockerfile/python_deps.include b/templates/tools/dockerfile/python_deps.include index 26c91f495d5..2c129814184 100644 --- a/templates/tools/dockerfile/python_deps.include +++ b/templates/tools/dockerfile/python_deps.include @@ -11,4 +11,4 @@ RUN apt-get update && apt-get install -y ${'\\'} # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 diff --git a/templates/tools/dockerfile/test/bazel/Dockerfile.template b/templates/tools/dockerfile/test/bazel/Dockerfile.template deleted file mode 100644 index 82f90bef681..00000000000 --- a/templates/tools/dockerfile/test/bazel/Dockerfile.template +++ /dev/null @@ -1,48 +0,0 @@ -%YAML 1.2 ---- | - # Copyright 2015, Google Inc. - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are - # met: - # - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # * Redistributions in binary form must reproduce the above - # copyright notice, this list of conditions and the following disclaimer - # in the documentation and/or other materials provided with the - # distribution. - # * Neither the name of Google Inc. nor the names of its - # contributors may be used to endorse or promote products derived from - # this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - FROM ubuntu:15.10 - - <%include file="../../apt_get_basic.include"/> - - #======================== - # Bazel installation - RUN apt-get install -y software-properties-common g++ - RUN echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list - RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add - - RUN apt-get -y update - RUN apt-get -y install bazel - - RUN mkdir -p /var/local/jenkins - - # Define the default command. - CMD ["bash"] - diff --git a/test/core/census/BUILD b/test/core/census/BUILD new file mode 100644 index 00000000000..49680ab91f0 --- /dev/null +++ b/test/core/census/BUILD @@ -0,0 +1,93 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "context_test", + srcs = ["context_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "mlog_test", + srcs = ["mlog_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "resource_test", + srcs = ["resource_test.c"], + copts = ["-std=c99"], + data = [ + ":data/resource_empty_name.pb", + ":data/resource_full.pb", + ":data/resource_minimal_good.pb", + ":data/resource_no_name.pb", + ":data/resource_no_numerator.pb", + ":data/resource_no_unit.pb", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "trace_context_test", + srcs = ["trace_context_test.c"], + copts = ["-std=c99"], + data = [ + ":data/context_empty.pb", + ":data/context_full.pb", + ":data/context_no_span_options.pb", + ":data/context_span_only.pb", + ":data/context_trace_only.pb", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD new file mode 100644 index 00000000000..c6590465f17 --- /dev/null +++ b/test/core/channel/BUILD @@ -0,0 +1,54 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "channel_args_test", + srcs = ["channel_args_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "channel_stack_test", + srcs = ["channel_stack_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/client_channel/parse_address_test.c b/test/core/client_channel/parse_address_test.c new file mode 100644 index 00000000000..37dd0fba52c --- /dev/null +++ b/test/core/client_channel/parse_address_test.c @@ -0,0 +1,116 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/ext/client_channel/parse_address.h" +#include "src/core/lib/iomgr/sockaddr.h" + +#include +#ifdef GRPC_HAVE_UNIX_SOCKET +#include +#endif + +#include + +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "test/core/util/test_config.h" + +#ifdef GRPC_HAVE_UNIX_SOCKET + +static void test_parse_unix(const char *uri_text, const char *pathname) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); + grpc_resolved_address addr; + + GPR_ASSERT(1 == parse_unix(uri, &addr)); + struct sockaddr_un *addr_un = (struct sockaddr_un *)addr.addr; + GPR_ASSERT(AF_UNIX == addr_un->sun_family); + GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname)); + + grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); +} + +#else /* GRPC_HAVE_UNIX_SOCKET */ + +static void test_parse_unix(const char *uri_text, const char *pathname) {} + +#endif /* GRPC_HAVE_UNIX_SOCKET */ + +static void test_parse_ipv4(const char *uri_text, const char *host, + unsigned short port) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); + grpc_resolved_address addr; + char ntop_buf[INET_ADDRSTRLEN]; + + GPR_ASSERT(1 == parse_ipv4(uri, &addr)); + struct sockaddr_in *addr_in = (struct sockaddr_in *)addr.addr; + GPR_ASSERT(AF_INET == addr_in->sin_family); + GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET, &addr_in->sin_addr, ntop_buf, + sizeof(ntop_buf))); + GPR_ASSERT(0 == strcmp(ntop_buf, host)); + GPR_ASSERT(ntohs(addr_in->sin_port) == port); + + grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); +} + +static void test_parse_ipv6(const char *uri_text, const char *host, + unsigned short port, uint32_t scope_id) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); + grpc_resolved_address addr; + char ntop_buf[INET6_ADDRSTRLEN]; + + GPR_ASSERT(1 == parse_ipv6(uri, &addr)); + struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr.addr; + GPR_ASSERT(AF_INET6 == addr_in6->sin6_family); + GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET6, &addr_in6->sin6_addr, ntop_buf, + sizeof(ntop_buf))); + GPR_ASSERT(0 == strcmp(ntop_buf, host)); + GPR_ASSERT(ntohs(addr_in6->sin6_port) == port); + GPR_ASSERT(addr_in6->sin6_scope_id == scope_id); + + grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + test_parse_unix("unix:/path/name", "/path/name"); + test_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345); + test_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0); + test_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2); +} diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c index 3e3401165cd..187757d5b31 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -69,7 +69,7 @@ static grpc_error *my_resolve_address(const char *name, const char *addr, static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx, const char *name) { grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns"); - grpc_uri *uri = grpc_uri_parse(name, 0); + grpc_uri *uri = grpc_uri_parse(exec_ctx, name, 0); GPR_ASSERT(uri); grpc_resolver_args args; memset(&args, 0, sizeof(args)); diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c index 9dd5aed0919..919a85d58f8 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_test.c @@ -43,7 +43,7 @@ static grpc_combiner *g_combiner; static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, @@ -61,7 +61,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c index 68831ab7c79..bc4f02c3394 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c @@ -57,7 +57,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, @@ -84,7 +84,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, diff --git a/test/core/client_channel/uri_fuzzer_test.c b/test/core/client_channel/uri_fuzzer_test.c index d2e3fb40eac..baadd4fc652 100644 --- a/test/core/client_channel/uri_fuzzer_test.c +++ b/test/core/client_channel/uri_fuzzer_test.c @@ -38,6 +38,7 @@ #include #include "src/core/ext/client_channel/uri_parser.h" +#include "src/core/lib/iomgr/exec_ctx.h" bool squelch = true; bool leak_check = true; @@ -47,10 +48,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memcpy(s, data, size); s[size] = 0; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *x; - if ((x = grpc_uri_parse(s, 1))) { + if ((x = grpc_uri_parse(&exec_ctx, s, 1))) { grpc_uri_destroy(x); } + grpc_exec_ctx_finish(&exec_ctx); gpr_free(s); return 0; } diff --git a/test/core/client_channel/uri_parser_test.c b/test/core/client_channel/uri_parser_test.c index 5f32d3270c1..8a127f72eb7 100644 --- a/test/core/client_channel/uri_parser_test.c +++ b/test/core/client_channel/uri_parser_test.c @@ -37,29 +37,35 @@ #include +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" static void test_succeeds(const char *uri_text, const char *scheme, const char *authority, const char *path, const char *query, const char *fragment) { - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp(scheme, uri->scheme)); GPR_ASSERT(0 == strcmp(authority, uri->authority)); GPR_ASSERT(0 == strcmp(path, uri->path)); GPR_ASSERT(0 == strcmp(query, uri->query)); GPR_ASSERT(0 == strcmp(fragment, uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } static void test_fails(const char *uri_text) { - GPR_ASSERT(NULL == grpc_uri_parse(uri_text, 0)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_ASSERT(NULL == grpc_uri_parse(&exec_ctx, uri_text, 0)); + grpc_exec_ctx_finish(&exec_ctx); } static void test_query_parts() { { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://foo/path?a&b=B&c=&#frag"; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -86,12 +92,14 @@ static void test_query_parts() { GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, "")); GPR_ASSERT(0 == strcmp("frag", uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } { /* test the current behavior of multiple query part values */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://auth/path?foo=bar=baz&foobar=="; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -103,12 +111,14 @@ static void test_query_parts() { GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo"))); GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar"))); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } { /* empty query */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://foo/path"; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -119,6 +129,7 @@ static void test_query_parts() { GPR_ASSERT(NULL == uri->query_parts); GPR_ASSERT(NULL == uri->query_parts_values); GPR_ASSERT(0 == strcmp("", uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } } @@ -142,6 +153,8 @@ int main(int argc, char **argv) { test_succeeds("http:?legit#twice", "http", "", "", "legit", "twice"); test_succeeds("http://foo?bar#lol?", "http", "foo", "", "bar", "lol?"); test_succeeds("http://foo?bar#lol?/", "http", "foo", "", "bar", "lol?/"); + test_succeeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "", + "[2001:db8::1%2]:12345", "", ""); test_fails("xyz"); test_fails("http:?dangling-pct-%0"); diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD new file mode 100644 index 00000000000..9ddb4c52b44 --- /dev/null +++ b/test/core/compression/BUILD @@ -0,0 +1,66 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "algorithm_test", + srcs = ["algorithm_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "compression_test", + srcs = ["compression_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "message_compress_test", + srcs = ["message_compress_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index a40fb8e083f..0cef7aa01df 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -63,8 +63,8 @@ cc_library( cc_library( name = 'http_proxy', - hdrs = ['fixtures/http_proxy.h'], - srcs = ['fixtures/http_proxy.c'], + hdrs = ['fixtures/http_proxy_fixture.h'], + srcs = ['fixtures/http_proxy_fixture.c'], copts = ['-std=c99'], deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util'] ) diff --git a/test/core/end2end/fixtures/h2_http_proxy.c b/test/core/end2end/fixtures/h2_http_proxy.c index 44b223664ab..55c65fa70ef 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.c +++ b/test/core/end2end/fixtures/h2_http_proxy.c @@ -49,7 +49,7 @@ #include "src/core/lib/support/env.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" -#include "test/core/end2end/fixtures/http_proxy.h" +#include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy_fixture.c similarity index 99% rename from test/core/end2end/fixtures/http_proxy.c rename to test/core/end2end/fixtures/http_proxy_fixture.c index 9ccb1263ee7..bcd1c9914b2 100644 --- a/test/core/end2end/fixtures/http_proxy.c +++ b/test/core/end2end/fixtures/http_proxy_fixture.c @@ -31,7 +31,7 @@ * */ -#include "test/core/end2end/fixtures/http_proxy.h" +#include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "src/core/lib/iomgr/sockaddr.h" diff --git a/test/core/end2end/fixtures/http_proxy.h b/test/core/end2end/fixtures/http_proxy_fixture.h similarity index 100% rename from test/core/end2end/fixtures/http_proxy.h rename to test/core/end2end/fixtures/http_proxy_fixture.h diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5834320218423296 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5834320218423296 new file mode 100644 index 00000000000..65cc6a22091 Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5834320218423296 differ diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 new file mode 100644 index 00000000000..49c02c2f123 Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 differ diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c index 7e4daaa84fe..948659ab2f4 100644 --- a/test/core/fling/fling_stream_test.c +++ b/test/core/fling/fling_stream_test.c @@ -31,22 +31,13 @@ * */ -#ifndef _POSIX_SOURCE -#define _POSIX_SOURCE -#endif - -#include -#include #include -#include #include -#include -#include -#include #include #include #include +#include #include "src/core/lib/support/string.h" #include "test/core/util/port.h" @@ -57,10 +48,7 @@ int main(int argc, char **argv) { int port = grpc_pick_unused_port_or_die(); char *args[10]; int status; - pid_t svr, cli; - /* seed rng with pid, so we don't end up with the same random numbers as a - concurrently running test binary */ - srand((unsigned)getpid()); + gpr_subprocess *svr, *cli; /* figure out where we are */ if (lslash) { memcpy(root, me, (size_t)(lslash - me)); @@ -69,45 +57,38 @@ int main(int argc, char **argv) { strcpy(root, "."); } /* start the server */ - svr = fork(); - if (svr == 0) { - gpr_asprintf(&args[0], "%s/fling_server", root); - args[1] = "--bind"; - gpr_join_host_port(&args[2], "::", port); - args[3] = "--no-secure"; - args[4] = 0; - execv(args[0], args); + gpr_asprintf(&args[0], "%s/fling_server%s", root, + gpr_subprocess_binary_extension()); + args[1] = "--bind"; + gpr_join_host_port(&args[2], "::", port); + args[3] = "--no-secure"; + svr = gpr_subprocess_create(4, (const char **)args); + gpr_free(args[0]); + gpr_free(args[2]); - gpr_free(args[0]); - gpr_free(args[2]); - return 1; - } - /* wait a little */ - sleep(2); /* start the client */ - cli = fork(); - if (cli == 0) { - gpr_asprintf(&args[0], "%s/fling_client", root); - args[1] = "--target"; - gpr_join_host_port(&args[2], "127.0.0.1", port); - args[3] = "--scenario=ping-pong-stream"; - args[4] = "--no-secure"; - args[5] = 0; - execv(args[0], args); + gpr_asprintf(&args[0], "%s/fling_client%s", root, + gpr_subprocess_binary_extension()); + args[1] = "--target"; + gpr_join_host_port(&args[2], "127.0.0.1", port); + args[3] = "--scenario=ping-pong-stream"; + args[4] = "--no-secure"; + args[5] = 0; + cli = gpr_subprocess_create(6, (const char **)args); + gpr_free(args[0]); + gpr_free(args[2]); - gpr_free(args[0]); - gpr_free(args[2]); - return 1; - } /* wait for completion */ printf("waiting for client\n"); - if (waitpid(cli, &status, 0) == -1) return 2; - if (!WIFEXITED(status)) return 4; - if (WEXITSTATUS(status)) return WEXITSTATUS(status); - printf("waiting for server\n"); - kill(svr, SIGINT); - if (waitpid(svr, &status, 0) == -1) return 2; - if (!WIFEXITED(status)) return 4; - if (WEXITSTATUS(status)) return WEXITSTATUS(status); - return 0; + if ((status = gpr_subprocess_join(cli))) { + gpr_subprocess_destroy(cli); + gpr_subprocess_destroy(svr); + return status; + } + gpr_subprocess_destroy(cli); + + gpr_subprocess_interrupt(svr); + status = gpr_subprocess_join(svr); + gpr_subprocess_destroy(svr); + return status; } diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD new file mode 100644 index 00000000000..eb8f3a9beb9 --- /dev/null +++ b/test/core/handshake/BUILD @@ -0,0 +1,64 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "client_ssl", + srcs = ["client_ssl.c"], + copts = ["-std=c99"], + data = [ + "//src/core/lib/tsi/test_creds:ca.pem", + "//src/core/lib/tsi/test_creds:server1.key", + "//src/core/lib/tsi/test_creds:server1.pem", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "server_ssl", + srcs = ["server_ssl.c"], + copts = ["-std=c99"], + data = [ + "//src/core/lib/tsi/test_creds:ca.pem", + "//src/core/lib/tsi/test_creds:server1.key", + "//src/core/lib/tsi/test_creds:server1.pem", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/iomgr/error_test.c b/test/core/iomgr/error_test.c new file mode 100644 index 00000000000..0452e4576a4 --- /dev/null +++ b/test/core/iomgr/error_test.c @@ -0,0 +1,142 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/lib/iomgr/error.h" + +#include +#include +#include +#include +#include + +#include + +#include "test/core/util/test_config.h" + +static void test_set_get_int() { + grpc_error* error = GRPC_ERROR_CREATE("Test"); + GPR_ASSERT(error); + intptr_t i = 0; + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_FILE_LINE, &i)); + GPR_ASSERT(i); // line set will never be 0 + GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); + GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_SIZE, &i)); + + intptr_t errnumber = 314; + error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, errnumber); + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); + GPR_ASSERT(i == errnumber); + + intptr_t http = 2; + error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, http); + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i)); + GPR_ASSERT(i == http); + + GRPC_ERROR_UNREF(error); +} + +static void test_set_get_str() { + grpc_error* error = GRPC_ERROR_CREATE("Test"); + + GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL)); + GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR)); + + const char* c = grpc_error_get_str(error, GRPC_ERROR_STR_FILE); + GPR_ASSERT(c); + GPR_ASSERT(strstr(c, "error_test.c")); // __FILE__ expands differently on + // Windows. All should at least + // contain error_test.c + + c = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "Test")); + + error = + grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "longer message"); + c = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "longer message")); + + GRPC_ERROR_UNREF(error); +} + +static void test_copy_and_unref() { + // error1 has one ref + grpc_error* error1 = grpc_error_set_str( + GRPC_ERROR_CREATE("Test"), GRPC_ERROR_STR_GRPC_MESSAGE, "message"); + const char* c = grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "message")); + + // error 1 has two refs + GRPC_ERROR_REF(error1); + // this gives error3 a ref to the new error, and decrements error1 to one ref + grpc_error* error3 = + grpc_error_set_str(error1, GRPC_ERROR_STR_SYSCALL, "syscall"); + GPR_ASSERT(error3 != error1); // should not be the same because of extra ref + c = grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "message")); + + // error 1 should not have a syscall but 3 should + GPR_ASSERT(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL)); + c = grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "syscall")); + + GRPC_ERROR_UNREF(error1); + GRPC_ERROR_UNREF(error3); +} + +static void print_error_strings() { + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNIMPLEMENTED); + error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, 0); + error = grpc_error_set_int(error, GRPC_ERROR_INT_SIZE, 666); + error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "message"); + gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); + GRPC_ERROR_UNREF(error); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + test_set_get_int(); + test_set_get_str(); + test_copy_and_unref(); + print_error_strings(); + grpc_shutdown(); + + return 0; +} diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c index 8569c697fe9..70a6c323e57 100644 --- a/test/core/iomgr/sockaddr_utils_test.c +++ b/test/core/iomgr/sockaddr_utils_test.c @@ -70,6 +70,12 @@ static grpc_resolved_address make_addr6(const uint8_t *data, size_t data_len) { return resolved_addr6; } +static void set_addr6_scope_id(grpc_resolved_address *addr, uint32_t scope_id) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr->addr; + GPR_ASSERT(addr6->sin6_family == AF_INET6); + addr6->sin6_scope_id = scope_id; +} + static const uint8_t kMapped[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 0, 2, 1}; @@ -222,6 +228,16 @@ static void test_sockaddr_to_string(void) { expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1); expect_sockaddr_uri("ipv6:[2001:db8::1]:12345", &input6); + set_addr6_scope_id(&input6, 2); + expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 0); + expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 1); + expect_sockaddr_uri("ipv6:[2001:db8::1%252]:12345", &input6); + + set_addr6_scope_id(&input6, 101); + expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 0); + expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 1); + expect_sockaddr_uri("ipv6:[2001:db8::1%25101]:12345", &input6); + input6 = make_addr6(kMapped, sizeof(kMapped)); expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0); expect_sockaddr_str("192.0.2.1:12345", &input6, 1); diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index efadddc0110..6e514324a5f 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -454,7 +454,8 @@ int main(int argc, char **argv) { const grpc_channel_args channel_args = {1, chan_args}; struct ifaddrs *ifa = NULL; struct ifaddrs *ifa_it; - test_addrs dst_addrs; + // Zalloc dst_addrs to avoid oversized frames. + test_addrs *dst_addrs = gpr_zalloc(sizeof(*dst_addrs)); grpc_test_init(argc, argv); grpc_init(); g_pollset = gpr_zalloc(grpc_pollset_size()); @@ -469,24 +470,25 @@ int main(int argc, char **argv) { gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno)); return EXIT_FAILURE; } - dst_addrs.naddrs = 0; - for (ifa_it = ifa; ifa_it != NULL && dst_addrs.naddrs < MAX_ADDRS; + dst_addrs->naddrs = 0; + for (ifa_it = ifa; ifa_it != NULL && dst_addrs->naddrs < MAX_ADDRS; ifa_it = ifa_it->ifa_next) { if (ifa_it->ifa_addr == NULL) { continue; } else if (ifa_it->ifa_addr->sa_family == AF_INET) { - dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in); + dst_addrs->addrs[dst_addrs->naddrs].addr.len = sizeof(struct sockaddr_in); } else if (ifa_it->ifa_addr->sa_family == AF_INET6) { - dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in6); + dst_addrs->addrs[dst_addrs->naddrs].addr.len = + sizeof(struct sockaddr_in6); } else { continue; } - memcpy(dst_addrs.addrs[dst_addrs.naddrs].addr.addr, ifa_it->ifa_addr, - dst_addrs.addrs[dst_addrs.naddrs].addr.len); + memcpy(dst_addrs->addrs[dst_addrs->naddrs].addr.addr, ifa_it->ifa_addr, + dst_addrs->addrs[dst_addrs->naddrs].addr.len); GPR_ASSERT( - grpc_sockaddr_set_port(&dst_addrs.addrs[dst_addrs.naddrs].addr, 0)); - test_addr_init_str(&dst_addrs.addrs[dst_addrs.naddrs]); - ++dst_addrs.naddrs; + grpc_sockaddr_set_port(&dst_addrs->addrs[dst_addrs->naddrs].addr, 0)); + test_addr_init_str(&dst_addrs->addrs[dst_addrs->naddrs]); + ++dst_addrs->naddrs; } freeifaddrs(ifa); ifa = NULL; @@ -495,20 +497,21 @@ int main(int argc, char **argv) { test_connect(1, NULL, NULL, false); test_connect(10, NULL, NULL, false); - /* Set dst_addrs.addrs[i].len=0 for dst_addrs that are unreachable with a "::" - listener. */ - test_connect(1, NULL, &dst_addrs, true); + /* Set dst_addrs->addrs[i].len=0 for dst_addrs that are unreachable with a + "::" listener. */ + test_connect(1, NULL, dst_addrs, true); /* Test connect(2) with dst_addrs. */ - test_connect(1, &channel_args, &dst_addrs, false); + test_connect(1, &channel_args, dst_addrs, false); /* Test connect(2) with dst_addrs. */ - test_connect(10, &channel_args, &dst_addrs, false); + test_connect(10, &channel_args, dst_addrs, false); grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx); grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); grpc_exec_ctx_finish(&exec_ctx); grpc_shutdown(); + gpr_free(dst_addrs); gpr_free(g_pollset); return EXIT_SUCCESS; } diff --git a/test/core/slice/percent_encoding_test.c b/test/core/slice/percent_encoding_test.c index 222e695fd42..89f81549552 100644 --- a/test/core/slice/percent_encoding_test.c +++ b/test/core/slice/percent_encoding_test.c @@ -146,6 +146,7 @@ int main(int argc, char **argv) { TEST_VECTOR("\x0f", "%0F", grpc_url_percent_encoding_unreserved_bytes); TEST_VECTOR("\xff", "%FF", grpc_url_percent_encoding_unreserved_bytes); TEST_VECTOR("\xee", "%EE", grpc_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("%2", "%252", grpc_url_percent_encoding_unreserved_bytes); TEST_NONCONFORMANT_VECTOR("%", "%", grpc_url_percent_encoding_unreserved_bytes); TEST_NONCONFORMANT_VECTOR("%A", "%A", diff --git a/test/core/support/BUILD b/test/core/support/BUILD index 08cee1441b2..3183510db9d 100644 --- a/test/core/support/BUILD +++ b/test/core/support/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "alloc_test", srcs = ["alloc_test.c"], diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index c1584131229..3d5e26ced31 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "alarm_test", srcs = ["alarm_test.c"], diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index 865b0c26ef5..08b2fd3332a 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -64,6 +64,13 @@ cc_test( copts = ['-std=c99'] ) +cc_test( + name = "stream_owned_slice_test", + srcs = ["stream_owned_slice_test.c"], + deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"], + copts = ['-std=c99'] +) + cc_test( name = "timeout_encoding_test", srcs = ["timeout_encoding_test.c"], diff --git a/test/core/transport/stream_owned_slice_test.c b/test/core/transport/stream_owned_slice_test.c new file mode 100644 index 00000000000..97ba1083f3c --- /dev/null +++ b/test/core/transport/stream_owned_slice_test.c @@ -0,0 +1,58 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/lib/transport/transport.h" + +#include "test/core/util/test_config.h" + +#include + +static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + uint8_t buffer[] = "abc123"; + grpc_stream_refcount r; + GRPC_STREAM_REF_INIT(&r, 1, do_nothing, NULL, "test"); + GPR_ASSERT(r.refs.count == 1); + grpc_slice slice = + grpc_slice_from_stream_owned_buffer(&r, buffer, sizeof(buffer)); + GPR_ASSERT(GRPC_SLICE_START_PTR(slice) == buffer); + GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == sizeof(buffer)); + GPR_ASSERT(r.refs.count == 2); + grpc_slice_unref(slice); + GPR_ASSERT(r.refs.count == 1); + + return 0; +} diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 5c90f1db44b..e6d0d247dbd 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -51,9 +51,8 @@ cc_library( "mock_endpoint.c", "parse_hexstring.c", "passthru_endpoint.c", - "port_posix.c", + "port.c", "port_server_client.c", - "port_windows.c", "reconnect_server.c", "slice_splitter.c", "test_tcp_server.c", diff --git a/test/core/util/port_uv.c b/test/core/util/port.c similarity index 78% rename from test/core/util/port_uv.c rename to test/core/util/port.c index 0c9c0d87d66..da1ed4e052d 100644 --- a/test/core/util/port_uv.c +++ b/test/core/util/port.c @@ -33,17 +33,24 @@ #include "src/core/lib/iomgr/port.h" #include "test/core/util/test_config.h" -#if defined(GRPC_UV) && defined(GRPC_TEST_PICK_PORT) +#if defined(GRPC_TEST_PICK_PORT) +#include "test/core/util/port.h" + +#include +#include +#include + +#include #include #include +#include -#include "src/core/lib/support/env.h" -#include "test/core/util/port.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include "test/core/util/port_server_client.h" -// Almost everything in this file has been copied from port_posix.c - static int *chosen_ports = NULL; static size_t num_chosen_ports = 0; @@ -51,7 +58,6 @@ static int free_chosen_port(int port) { size_t i; int found = 0; size_t found_at = 0; - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); /* Find the port and erase it from the list, then tell the server it can be freed. */ for (i = 0; i < num_chosen_ports; i++) { @@ -64,24 +70,16 @@ static int free_chosen_port(int port) { if (found) { chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1]; num_chosen_ports--; - if (env) { - grpc_free_port_using_server(env, port); - } + grpc_free_port_using_server(port); } - gpr_free(env); return found; } static void free_chosen_ports(void) { - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - if (env != NULL) { - size_t i; - for (i = 0; i < num_chosen_ports; i++) { - grpc_free_port_using_server(env, chosen_ports[i]); - } - gpr_free(env); + size_t i; + for (i = 0; i < num_chosen_ports; i++) { + grpc_free_port_using_server(chosen_ports[i]); } - gpr_free(chosen_ports); } @@ -95,23 +93,27 @@ static void chose_port(int port) { } int grpc_pick_unused_port(void) { - // Currently only works with the port server - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - GPR_ASSERT(env); - int port = grpc_pick_port_using_server(env); - gpr_free(env); + int port = grpc_pick_port_using_server(); if (port != 0) { chose_port(port); } + return port; } int grpc_pick_unused_port_or_die(void) { int port = grpc_pick_unused_port(); - GPR_ASSERT(port > 0); + if (port == 0) { + fprintf(stderr, + "gRPC tests require a helper port server to allocate ports used \n" + "during the test.\n\n" + "This server is not currently running.\n\n" + "To start it, run tools/run_tests/start_port_server.py\n\n"); + exit(1); + } return port; } void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); } -#endif /* GRPC_UV && GRPC_TEST_PICK_PORT */ +#endif /* GRPC_TEST_PICK_PORT */ diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c deleted file mode 100644 index 4a42e4c7021..00000000000 --- a/test/core/util/port_posix.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/lib/iomgr/port.h" -#include "test/core/util/test_config.h" -#if defined(GRPC_POSIX_SOCKET) && defined(GRPC_TEST_PICK_PORT) - -#include "test/core/util/port.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/lib/http/httpcli.h" -#include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/support/env.h" -#include "test/core/util/port_server_client.h" - -#define NUM_RANDOM_PORTS_TO_PICK 100 - -static int *chosen_ports = NULL; -static size_t num_chosen_ports = 0; - -static int has_port_been_chosen(int port) { - size_t i; - for (i = 0; i < num_chosen_ports; i++) { - if (chosen_ports[i] == port) { - return 1; - } - } - return 0; -} - -static int free_chosen_port(int port) { - size_t i; - int found = 0; - size_t found_at = 0; - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - /* Find the port and erase it from the list, then tell the server it can be - freed. */ - for (i = 0; i < num_chosen_ports; i++) { - if (chosen_ports[i] == port) { - GPR_ASSERT(found == 0); - found = 1; - found_at = i; - } - } - if (found) { - chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1]; - num_chosen_ports--; - if (env) { - grpc_free_port_using_server(env, port); - } - } - gpr_free(env); - return found; -} - -static void free_chosen_ports(void) { - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - if (env != NULL) { - size_t i; - for (i = 0; i < num_chosen_ports; i++) { - grpc_free_port_using_server(env, chosen_ports[i]); - } - gpr_free(env); - } - - gpr_free(chosen_ports); -} - -static void chose_port(int port) { - if (chosen_ports == NULL) { - atexit(free_chosen_ports); - } - num_chosen_ports++; - chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports); - chosen_ports[num_chosen_ports - 1] = port; -} - -static bool is_port_available(int *port, bool is_tcp) { - GPR_ASSERT(*port >= 0); - GPR_ASSERT(*port <= 65535); - - /* For a port to be considered available, the kernel must support - at least one of (IPv6, IPv4), and the port must be available - on each supported family. */ - bool got_socket = false; - for (int is_ipv6 = 1; is_ipv6 >= 0; is_ipv6--) { - const int fd = - socket(is_ipv6 ? AF_INET6 : AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, - is_tcp ? IPPROTO_TCP : 0); - if (fd >= 0) { - got_socket = true; - } else { - continue; - } - - /* Reuseaddr lets us start up a server immediately after it exits */ - const int one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) { - gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno)); - close(fd); - return false; - } - - /* Try binding to port */ - grpc_resolved_address addr; - if (is_ipv6) { - grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */ - } else { - grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */ - } - if (bind(fd, (struct sockaddr *)addr.addr, (socklen_t)addr.len) < 0) { - gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno)); - close(fd); - return false; - } - - /* Get the bound port number */ - if (getsockname(fd, (struct sockaddr *)addr.addr, (socklen_t *)&addr.len) < - 0) { - gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno)); - close(fd); - return false; - } - GPR_ASSERT(addr.len <= sizeof(addr.addr)); - const int actual_port = grpc_sockaddr_get_port(&addr); - GPR_ASSERT(actual_port > 0); - if (*port == 0) { - *port = actual_port; - } else { - GPR_ASSERT(*port == actual_port); - } - - close(fd); - } - if (!got_socket) { - gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno)); - return false; - } - return true; -} - -int grpc_pick_unused_port(void) { - /* We repeatedly pick a port and then see whether or not it is - available for use both as a TCP socket and a UDP socket. First, we - pick a random large port number. For subsequent - iterations, we bind to an anonymous port and let the OS pick the - port number. The random port picking reduces the probability of - races with other processes on kernels that want to reuse the same - port numbers over and over. */ - - /* In alternating iterations we trial UDP ports before TCP ports UDP - ports -- it could be the case that this machine has been using up - UDP ports and they are scarcer. */ - - /* Type of port to first pick in next iteration */ - bool is_tcp = true; - int trial = 0; - - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - if (env) { - int port = grpc_pick_port_using_server(env); - gpr_free(env); - if (port != 0) { - chose_port(port); - } - return port; - } - - for (;;) { - int port; - trial++; - if (trial == 1) { - port = getpid() % (65536 - 30000) + 30000; - } else if (trial <= NUM_RANDOM_PORTS_TO_PICK) { - port = rand() % (65536 - 30000) + 30000; - } else { - port = 0; - } - - if (has_port_been_chosen(port)) { - continue; - } - - if (!is_port_available(&port, is_tcp)) { - continue; - } - - GPR_ASSERT(port > 0); - /* Check that the port # is free for the other type of socket also */ - if (!is_port_available(&port, !is_tcp)) { - /* In the next iteration trial to bind to the other type first - because perhaps it is more rare. */ - is_tcp = !is_tcp; - continue; - } - - chose_port(port); - return port; - } - - /* The port iterator reached the end without finding a suitable port. */ - return 0; -} - -int grpc_pick_unused_port_or_die(void) { - int port = grpc_pick_unused_port(); - GPR_ASSERT(port > 0); - return port; -} - -void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); } - -#endif /* GRPC_POSIX_SOCKET && GRPC_TEST_PICK_PORT */ diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c index f7d723a7d29..38054dd1e74 100644 --- a/test/core/util/port_server_client.c +++ b/test/core/util/port_server_client.c @@ -74,7 +74,7 @@ static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_unlock(pr->mu); } -void grpc_free_port_using_server(char *server, int port) { +void grpc_free_port_using_server(int port) { grpc_httpcli_context context; grpc_httpcli_request req; grpc_httpcli_response rsp; @@ -95,7 +95,7 @@ void grpc_free_port_using_server(char *server, int port) { shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops, grpc_schedule_on_exec_ctx); - req.host = server; + req.host = GRPC_PORT_SERVER_ADDRESS; gpr_asprintf(&path, "/drop/%d", port); req.http.path = path; @@ -162,6 +162,15 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, if (failed) { grpc_httpcli_request req; memset(&req, 0, sizeof(req)); + if (pr->retries >= 5) { + gpr_mu_lock(pr->mu); + pr->port = 0; + GRPC_LOG_IF_ERROR( + "pollset_kick", + grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), NULL)); + gpr_mu_unlock(pr->mu); + return; + } GPR_ASSERT(pr->retries < 10); gpr_sleep_until(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), @@ -198,7 +207,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_unlock(pr->mu); } -int grpc_pick_port_using_server(char *server) { +int grpc_pick_port_using_server(void) { grpc_httpcli_context context; grpc_httpcli_request req; portreq pr; @@ -215,10 +224,10 @@ int grpc_pick_port_using_server(char *server) { shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops, grpc_schedule_on_exec_ctx); pr.port = -1; - pr.server = server; + pr.server = GRPC_PORT_SERVER_ADDRESS; pr.ctx = &context; - req.host = server; + req.host = GRPC_PORT_SERVER_ADDRESS; req.http.path = "/get"; grpc_httpcli_context_init(&context); diff --git a/test/core/util/port_server_client.h b/test/core/util/port_server_client.h index 437006495c9..70471ecb8ac 100644 --- a/test/core/util/port_server_client.h +++ b/test/core/util/port_server_client.h @@ -36,7 +36,10 @@ // C interface to port_server.py -int grpc_pick_port_using_server(char *server); -void grpc_free_port_using_server(char *server, int port); +// must be synchronized with tools/run_tests/python_utils/start_port_server.py +#define GRPC_PORT_SERVER_ADDRESS "localhost:32766" + +int grpc_pick_port_using_server(void); +void grpc_free_port_using_server(int port); #endif // GRPC_TEST_CORE_UTIL_PORT_SERVER_CLIENT_H diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c deleted file mode 100644 index 0c50a466441..00000000000 --- a/test/core/util/port_windows.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/lib/iomgr/port.h" -#include "test/core/util/test_config.h" -#if defined(GRPC_WINSOCK_SOCKET) && defined(GRPC_TEST_PICK_PORT) - -#include "src/core/lib/iomgr/sockaddr.h" - -#include "test/core/util/port.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "src/core/lib/http/httpcli.h" -#include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/support/env.h" -#include "test/core/util/port_server_client.h" - -#if GPR_GETPID_IN_UNISTD_H -#include -static int _getpid() { return getpid(); } -#endif - -#define NUM_RANDOM_PORTS_TO_PICK 100 - -static int *chosen_ports = NULL; -static size_t num_chosen_ports = 0; - -static int has_port_been_chosen(int port) { - size_t i; - for (i = 0; i < num_chosen_ports; i++) { - if (chosen_ports[i] == port) { - return 1; - } - } - return 0; -} - -static int free_chosen_port(int port) { - size_t i; - int found = 0; - size_t found_at = 0; - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - if (env != NULL) { - /* Find the port and erase it from the list, then tell the server it can be - freed. */ - for (i = 0; i < num_chosen_ports; i++) { - if (chosen_ports[i] == port) { - GPR_ASSERT(found == 0); - found = 1; - found_at = i; - } - } - if (found) { - chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1]; - grpc_free_port_using_server(env, port); - num_chosen_ports--; - } - } - return found; -} - -static void free_chosen_ports(void) { - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - if (env != NULL) { - size_t i; - for (i = 0; i < num_chosen_ports; i++) { - grpc_free_port_using_server(env, chosen_ports[i]); - } - gpr_free(env); - } - - gpr_free(chosen_ports); -} - -static void chose_port(int port) { - if (chosen_ports == NULL) { - atexit(free_chosen_ports); - } - num_chosen_ports++; - chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports); - chosen_ports[num_chosen_ports - 1] = port; -} - -static int is_port_available(int *port, int is_tcp) { - const int proto = is_tcp ? IPPROTO_TCP : 0; - const SOCKET fd = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, proto); - int one = 1; - struct sockaddr_in addr; - socklen_t alen = sizeof(addr); - int actual_port; - - GPR_ASSERT(*port >= 0); - GPR_ASSERT(*port <= 65535); - if (INVALID_SOCKET == fd) { - gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno)); - return 0; - } - - /* Reuseaddr lets us start up a server immediately after it exits */ - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, - sizeof(one)) < 0) { - gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno)); - closesocket(fd); - return 0; - } - - /* Try binding to port */ - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons((u_short)*port); - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno)); - closesocket(fd); - return 0; - } - - /* Get the bound port number */ - if (getsockname(fd, (struct sockaddr *)&addr, &alen) < 0) { - gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno)); - closesocket(fd); - return 0; - } - GPR_ASSERT(alen <= (socklen_t)sizeof(addr)); - actual_port = ntohs(addr.sin_port); - GPR_ASSERT(actual_port > 0); - if (*port == 0) { - *port = actual_port; - } else { - GPR_ASSERT(*port == actual_port); - } - - closesocket(fd); - return 1; -} - -int grpc_pick_unused_port(void) { - /* We repeatedly pick a port and then see whether or not it is - available for use both as a TCP socket and a UDP socket. First, we - pick a random large port number. For subsequent - iterations, we bind to an anonymous port and let the OS pick the - port number. The random port picking reduces the probability of - races with other processes on kernels that want to reuse the same - port numbers over and over. */ - - /* In alternating iterations we trial UDP ports before TCP ports UDP - ports -- it could be the case that this machine has been using up - UDP ports and they are scarcer. */ - - /* Type of port to first pick in next iteration */ - int is_tcp = 1; - int trial = 0; - - char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); - if (env) { - int port = grpc_pick_port_using_server(env); - gpr_free(env); - if (port != 0) { - return port; - } - } - - for (;;) { - int port; - trial++; - if (trial == 1) { - port = _getpid() % (65536 - 30000) + 30000; - } else if (trial <= NUM_RANDOM_PORTS_TO_PICK) { - port = rand() % (65536 - 30000) + 30000; - } else { - port = 0; - } - - if (has_port_been_chosen(port)) { - continue; - } - - if (!is_port_available(&port, is_tcp)) { - continue; - } - - GPR_ASSERT(port > 0); - /* Check that the port # is free for the other type of socket also */ - if (!is_port_available(&port, !is_tcp)) { - /* In the next iteration trial to bind to the other type first - because perhaps it is more rare. */ - is_tcp = !is_tcp; - continue; - } - - /* TODO(ctiller): consider caching this port in some structure, to avoid - handing it out again */ - - chose_port(port); - return port; - } - - /* The port iterator reached the end without finding a suitable port. */ - return 0; -} - -int grpc_pick_unused_port_or_die(void) { - int port = grpc_pick_unused_port(); - GPR_ASSERT(port > 0); - return port; -} - -void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); } - -#endif /* GRPC_WINSOCK_SOCKET && GRPC_TEST_PICK_PORT */ diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD new file mode 100644 index 00000000000..14d5733da2c --- /dev/null +++ b/test/cpp/codegen/BUILD @@ -0,0 +1,77 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "codegen_test_full", + srcs = ["codegen_test_full.cc"], + deps = [ + "//:grpc++", + "//external:gtest", + "//test/core/util:gpr_test_util", + ], +) + +cc_test( + name = "codegen_test_minimal", + srcs = ["codegen_test_minimal.cc"], + deps = [ + "//:grpc++", + "//external:gtest", + "//test/core/util:gpr_test_util", + ], +) + +cc_test( + name = "proto_utils_test", + srcs = ["proto_utils_test.cc"], + deps = [ + "//:grpc++", + "//external:gtest", + "//test/core/util:gpr_test_util", + ], +) + +cc_test( + name = "golden_file_test", + srcs = ["golden_file_test.cc"], + args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h"], + data = [ + ":compiler_test_golden", + "//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen", + ], + deps = [ + "//:grpc++", + "//external:gflags", + "//external:gtest", + "//src/proto/grpc/testing:compiler_test_proto", + "//test/core/util:gpr_test_util", + ], +) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 0b82f2a59f3..fd26a17ac11 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -1,4 +1,4 @@ -// Generated by the gRPC protobuf plugin. +// Generated by the gRPC C++ plugin. // If you make any local change, they will be lost. // source: src/proto/grpc/testing/compiler_test.proto // Original file comments: diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc index ec08d08de66..158a4d933c9 100644 --- a/test/cpp/codegen/golden_file_test.cc +++ b/test/cpp/codegen/golden_file_test.cc @@ -34,15 +34,18 @@ #include #include +#include #include -// These paths rely on the fact that we run our tests under grpc/ -const char kGeneratedFilePath[] = - "gens/src/proto/grpc/testing/compiler_test.grpc.pb.h"; +DEFINE_string(generated_file_path, "", + "path to the generated compiler_test.grpc.pb.h file"); + const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden"; TEST(GoldenFileTest, TestGeneratedFile) { - std::ifstream generated(kGeneratedFilePath); + ASSERT_FALSE(FLAGS_generated_file_path.empty()); + + std::ifstream generated(FLAGS_generated_file_path); std::ifstream golden(kGoldenFilePath); ASSERT_TRUE(generated.good()); @@ -60,5 +63,6 @@ TEST(GoldenFileTest, TestGeneratedFile) { int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); + ::google::ParseCommandLineFlags(&argc, &argv, true); return RUN_ALL_TESTS(); } diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc index b96e9fac36e..01c07823cfe 100644 --- a/test/cpp/interop/http2_client.cc +++ b/test/cpp/interop/http2_client.cc @@ -65,7 +65,9 @@ Http2Client::ServiceStub::ServiceStub(std::shared_ptr channel) TestService::Stub* Http2Client::ServiceStub::Get() { return stub_.get(); } Http2Client::Http2Client(std::shared_ptr channel) - : serviceStub_(channel), channel_(channel) {} + : serviceStub_(channel), + channel_(channel), + defaultRequest_(BuildDefaultRequest()) {} bool Http2Client::AssertStatusCode(const Status& s, StatusCode expected_code) { if (s.error_code() == expected_code) { @@ -77,18 +79,24 @@ bool Http2Client::AssertStatusCode(const Status& s, StatusCode expected_code) { abort(); } -bool Http2Client::DoRstAfterHeader() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header"); - +Status Http2Client::SendUnaryCall(SimpleResponse* response) { ClientContext context; + return serviceStub_.Get()->UnaryCall(&context, defaultRequest_, response); +} + +SimpleRequest Http2Client::BuildDefaultRequest() { SimpleRequest request; - SimpleResponse response; request.set_response_size(kLargeResponseSize); grpc::string payload(kLargeRequestSize, '\0'); request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); + return request; +} + +bool Http2Client::DoRstAfterHeader() { + gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header"); - Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::UNKNOWN); + SimpleResponse response; + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); GPR_ASSERT(!response.has_payload()); // no data should be received gpr_log(GPR_DEBUG, "Done testing reset stream after header"); @@ -98,15 +106,8 @@ bool Http2Client::DoRstAfterHeader() { bool Http2Client::DoRstAfterData() { gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data"); - ClientContext context; - SimpleRequest request; SimpleResponse response; - request.set_response_size(kLargeResponseSize); - grpc::string payload(kLargeRequestSize, '\0'); - request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); - - Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::UNKNOWN); + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); GPR_ASSERT(response.has_payload()); // data should be received gpr_log(GPR_DEBUG, "Done testing reset stream after data"); @@ -116,15 +117,8 @@ bool Http2Client::DoRstAfterData() { bool Http2Client::DoRstDuringData() { gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data"); - ClientContext context; - SimpleRequest request; SimpleResponse response; - request.set_response_size(kLargeResponseSize); - grpc::string payload(kLargeRequestSize, '\0'); - request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); - - Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::UNKNOWN); + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); GPR_ASSERT(!response.has_payload()); // no data should be received gpr_log(GPR_DEBUG, "Done testing reset stream during data"); @@ -133,56 +127,37 @@ bool Http2Client::DoRstDuringData() { bool Http2Client::DoGoaway() { gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway"); + SimpleResponse response; + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); + GPR_ASSERT(response.payload().body() == + grpc::string(kLargeResponseSize, '\0')); - int numCalls = 2; - for (int i = 0; i < numCalls; i++) { - ClientContext context; - SimpleRequest request; - SimpleResponse response; - request.set_response_size(kLargeResponseSize); - grpc::string payload(kLargeRequestSize, '\0'); - request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); - - Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::OK); - GPR_ASSERT(response.payload().body() == - grpc::string(kLargeResponseSize, '\0')); - } + // Sleep for one second to give time for client to receive goaway frame. + gpr_timespec sleep_time = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1, GPR_TIMESPAN)); + gpr_sleep_until(sleep_time); + response.Clear(); + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); + GPR_ASSERT(response.payload().body() == + grpc::string(kLargeResponseSize, '\0')); gpr_log(GPR_DEBUG, "Done testing goaway"); return true; } bool Http2Client::DoPing() { gpr_log(GPR_DEBUG, "Sending RPC and expecting ping"); - - ClientContext context; - SimpleRequest request; SimpleResponse response; - request.set_response_size(kLargeResponseSize); - grpc::string payload(kLargeRequestSize, '\0'); - request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); - - Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::OK); + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); GPR_ASSERT(response.payload().body() == grpc::string(kLargeResponseSize, '\0')); - gpr_log(GPR_DEBUG, "Done testing ping"); return true; } void Http2Client::MaxStreamsWorker(std::shared_ptr channel) { - ClientContext context; - SimpleRequest request; SimpleResponse response; - request.set_response_size(kLargeResponseSize); - grpc::string payload(kLargeRequestSize, '\0'); - request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); - - Status s = - TestService::NewStub(channel)->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::OK); + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); GPR_ASSERT(response.payload().body() == grpc::string(kLargeResponseSize, '\0')); } @@ -192,15 +167,8 @@ bool Http2Client::DoMaxStreams() { // Make an initial call on the channel to ensure the server's max streams // setting is received - ClientContext context; - SimpleRequest request; SimpleResponse response; - request.set_response_size(kLargeResponseSize); - grpc::string payload(kLargeRequestSize, '\0'); - request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); - Status s = - TestService::NewStub(channel_)->UnaryCall(&context, request, &response); - AssertStatusCode(s, grpc::StatusCode::OK); + AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); GPR_ASSERT(response.payload().body() == grpc::string(kLargeResponseSize, '\0')); @@ -240,7 +208,11 @@ int main(int argc, char** argv) { char host_port[host_port_buf_size]; snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(), FLAGS_server_port); - grpc::testing::Http2Client client(grpc::CreateTestChannel(host_port, false)); + std::shared_ptr channel = + grpc::CreateTestChannel(host_port, false); + GPR_ASSERT(channel->WaitForConnected(gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN)))); + grpc::testing::Http2Client client(channel); gpr_log(GPR_INFO, "Testing case: %s", FLAGS_test_case.c_str()); int ret = 0; if (FLAGS_test_case == "rst_after_header") { diff --git a/test/cpp/interop/http2_client.h b/test/cpp/interop/http2_client.h index 6a315f5abba..12df5d26bc2 100644 --- a/test/cpp/interop/http2_client.h +++ b/test/cpp/interop/http2_client.h @@ -70,8 +70,11 @@ class Http2Client { void MaxStreamsWorker(std::shared_ptr channel); bool AssertStatusCode(const Status& s, StatusCode expected_code); + Status SendUnaryCall(SimpleResponse* response); + SimpleRequest BuildDefaultRequest(); ServiceStub serviceStub_; std::shared_ptr channel_; + SimpleRequest defaultRequest_; }; } // namespace testing diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 76d50302769..014e2b96b55 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -55,28 +56,106 @@ extern "C" { #include "src/core/lib/transport/transport_impl.h" } +#include "src/cpp/client/create_channel_internal.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" -static struct Init { - Init() { grpc_init(); } - ~Init() { grpc_shutdown(); } -} g_init; +auto &force_library_initialization = Library::get(); -static void BM_InsecureChannelWithDefaults(benchmark::State &state) { - grpc_channel *channel = - grpc_insecure_channel_create("localhost:12345", NULL, NULL); +void BM_Zalloc(benchmark::State &state) { + // speed of light for call creation is zalloc, so benchmark a few interesting + // sizes + size_t sz = state.range(0); + while (state.KeepRunning()) { + gpr_free(gpr_zalloc(sz)); + } +} +BENCHMARK(BM_Zalloc) + ->Arg(64) + ->Arg(128) + ->Arg(256) + ->Arg(512) + ->Arg(1024) + ->Arg(1536) + ->Arg(2048) + ->Arg(3072) + ->Arg(4096) + ->Arg(5120) + ->Arg(6144) + ->Arg(7168); + +class BaseChannelFixture { + public: + BaseChannelFixture(grpc_channel *channel) : channel_(channel) {} + ~BaseChannelFixture() { grpc_channel_destroy(channel_); } + + grpc_channel *channel() const { return channel_; } + + private: + grpc_channel *const channel_; +}; + +class InsecureChannel : public BaseChannelFixture { + public: + InsecureChannel() + : BaseChannelFixture( + grpc_insecure_channel_create("localhost:1234", NULL, NULL)) {} +}; + +class LameChannel : public BaseChannelFixture { + public: + LameChannel() + : BaseChannelFixture(grpc_lame_client_channel_create( + "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah")) {} +}; + +template +static void BM_CallCreateDestroy(benchmark::State &state) { + TrackCounters track_counters; + Fixture fixture; grpc_completion_queue *cq = grpc_completion_queue_create(NULL); - grpc_slice method = grpc_slice_from_static_string("/foo/bar"); gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + void *method_hdl = + grpc_channel_register_call(fixture.channel(), "/foo/bar", NULL, NULL); while (state.KeepRunning()) { - grpc_call_destroy(grpc_channel_create_call(channel, NULL, - GRPC_PROPAGATE_DEFAULTS, cq, - method, NULL, deadline, NULL)); + grpc_call_destroy(grpc_channel_create_registered_call( + fixture.channel(), NULL, GRPC_PROPAGATE_DEFAULTS, cq, method_hdl, + deadline, NULL)); } - grpc_channel_destroy(channel); grpc_completion_queue_destroy(cq); + track_counters.Finish(state); +} + +BENCHMARK_TEMPLATE(BM_CallCreateDestroy, InsecureChannel); +BENCHMARK_TEMPLATE(BM_CallCreateDestroy, LameChannel); + +static void *tag(int i) { + return reinterpret_cast(static_cast(i)); +} + +static void BM_LameChannelCallCreateCpp(benchmark::State &state) { + TrackCounters track_counters; + auto stub = + grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal( + "", grpc_lame_client_channel_create( + "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"))); + grpc::CompletionQueue cq; + grpc::testing::EchoRequest send_request; + grpc::testing::EchoResponse recv_response; + grpc::Status recv_status; + while (state.KeepRunning()) { + grpc::ClientContext cli_ctx; + auto reader = stub->AsyncEcho(&cli_ctx, send_request, &cq); + reader->Finish(&recv_response, &recv_status, tag(0)); + void *t; + bool ok; + GPR_ASSERT(cq.Next(&t, &ok)); + GPR_ASSERT(ok); + } + track_counters.Finish(state); } -BENCHMARK(BM_InsecureChannelWithDefaults); +BENCHMARK(BM_LameChannelCallCreateCpp); static void FilterDestroy(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -289,6 +368,7 @@ class SendEmptyMetadata { // perform on said filter. template static void BM_IsolatedFilter(benchmark::State &state) { + TrackCounters track_counters; Fixture fixture; std::ostringstream label; @@ -344,6 +424,7 @@ static void BM_IsolatedFilter(benchmark::State &state) { gpr_free(call_stack); state.SetLabel(label.str()); + track_counters.Finish(state); } typedef Fixture NoFilter; diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 5fb3f371306..563db758f71 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -42,18 +42,17 @@ extern "C" { #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/static_metadata.h" } +#include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" -static struct Init { - Init() { grpc_init(); } - ~Init() { grpc_shutdown(); } -} g_init; +auto &force_library_initialization = Library::get(); //////////////////////////////////////////////////////////////////////////////// // HPACK encoder // static void BM_HpackEncoderInitDestroy(benchmark::State &state) { + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_chttp2_hpack_compressor c; while (state.KeepRunning()) { @@ -62,11 +61,13 @@ static void BM_HpackEncoderInitDestroy(benchmark::State &state) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_HpackEncoderInitDestroy); template static void BM_HpackEncoderEncodeHeader(benchmark::State &state) { + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_metadata_batch b; @@ -102,6 +103,7 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) { << " header_bytes/iter:" << (static_cast(stats.header_bytes) / static_cast(state.iterations())); state.SetLabel(label.str()); + track_counters.Finish(state); } namespace hpack_encoder_fixtures { @@ -216,6 +218,7 @@ BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, // static void BM_HpackParserInitDestroy(benchmark::State &state) { + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_chttp2_hpack_parser p; while (state.KeepRunning()) { @@ -224,6 +227,7 @@ static void BM_HpackParserInitDestroy(benchmark::State &state) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_HpackParserInitDestroy); @@ -234,6 +238,7 @@ static void UnrefHeader(grpc_exec_ctx *exec_ctx, void *user_data, template static void BM_HpackParserParseHeader(benchmark::State &state) { + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; std::vector init_slices = Fixture::GetInitSlices(); std::vector benchmark_slices = Fixture::GetBenchmarkSlices(); @@ -252,6 +257,7 @@ static void BM_HpackParserParseHeader(benchmark::State &state) { } grpc_chttp2_hpack_parser_destroy(&exec_ctx, &p); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } namespace hpack_parser_fixtures { diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index 1f54e8c8b17..28a385b6c11 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2017, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,86 +42,47 @@ extern "C" { #include "src/core/lib/support/spinlock.h" } +#include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" -#include - -#ifdef GPR_LOW_LEVEL_COUNTERS -extern "C" gpr_atm gpr_mu_locks; -#endif - -static class InitializeStuff { - public: - InitializeStuff() { grpc_init(); } - ~InitializeStuff() { grpc_shutdown(); } -} initialize_stuff; - -class TrackCounters { - public: - TrackCounters(benchmark::State& state) : state_(state) {} - - ~TrackCounters() { - std::ostringstream out; -#ifdef GPR_LOW_LEVEL_COUNTERS - out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) - - mu_locks_at_start_) / - (double)state_.iterations()) - << " atm_cas/iter:" - << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_cas) - - atm_cas_at_start_) / - (double)state_.iterations()) - << " atm_add/iter:" - << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) - - atm_add_at_start_) / - (double)state_.iterations()); -#endif - state_.SetLabel(out.str()); - } - - private: - benchmark::State& state_; -#ifdef GPR_LOW_LEVEL_COUNTERS - const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks); - const size_t atm_cas_at_start_ = - gpr_atm_no_barrier_load(&gpr_counter_atm_cas); - const size_t atm_add_at_start_ = - gpr_atm_no_barrier_load(&gpr_counter_atm_add); -#endif -}; +auto& force_library_initialization = Library::get(); static void BM_NoOpExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; while (state.KeepRunning()) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx_finish(&exec_ctx); } + track_counters.Finish(state); } BENCHMARK(BM_NoOpExecCtx); static void BM_WellFlushed(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; while (state.KeepRunning()) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_WellFlushed); static void DoNothing(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {} static void BM_ClosureInitAgainstExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_closure c; while (state.KeepRunning()) { benchmark::DoNotOptimize( grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx)); } + track_counters.Finish(state); } BENCHMARK(BM_ClosureInitAgainstExecCtx); static void BM_ClosureInitAgainstCombiner(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_combiner* combiner = grpc_combiner_create(NULL); grpc_closure c; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -131,11 +92,12 @@ static void BM_ClosureInitAgainstCombiner(benchmark::State& state) { } GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureInitAgainstCombiner); static void BM_ClosureRunOnExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_closure c; grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -144,11 +106,12 @@ static void BM_ClosureRunOnExecCtx(benchmark::State& state) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureRunOnExecCtx); static void BM_ClosureCreateAndRun(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; while (state.KeepRunning()) { grpc_closure_run(&exec_ctx, grpc_closure_create(DoNothing, NULL, @@ -156,11 +119,12 @@ static void BM_ClosureCreateAndRun(benchmark::State& state) { GRPC_ERROR_NONE); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureCreateAndRun); static void BM_ClosureInitAndRun(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure c; while (state.KeepRunning()) { @@ -169,11 +133,12 @@ static void BM_ClosureInitAndRun(benchmark::State& state) { GRPC_ERROR_NONE); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureInitAndRun); static void BM_ClosureSchedOnExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_closure c; grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -182,11 +147,12 @@ static void BM_ClosureSchedOnExecCtx(benchmark::State& state) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSchedOnExecCtx); static void BM_ClosureSched2OnExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_closure c1; grpc_closure c2; grpc_closure_init(&c1, DoNothing, NULL, grpc_schedule_on_exec_ctx); @@ -198,11 +164,12 @@ static void BM_ClosureSched2OnExecCtx(benchmark::State& state) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSched2OnExecCtx); static void BM_ClosureSched3OnExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_closure c1; grpc_closure c2; grpc_closure c3; @@ -217,11 +184,12 @@ static void BM_ClosureSched3OnExecCtx(benchmark::State& state) { grpc_exec_ctx_flush(&exec_ctx); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSched3OnExecCtx); static void BM_AcquireMutex(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; // for comparison with the combiner stuff below gpr_mu mu; gpr_mu_init(&mu); @@ -232,11 +200,12 @@ static void BM_AcquireMutex(benchmark::State& state) { gpr_mu_unlock(&mu); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_AcquireMutex); static void BM_TryAcquireMutex(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; // for comparison with the combiner stuff below gpr_mu mu; gpr_mu_init(&mu); @@ -250,11 +219,12 @@ static void BM_TryAcquireMutex(benchmark::State& state) { } } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_TryAcquireMutex); static void BM_AcquireSpinlock(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; // for comparison with the combiner stuff below gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -264,11 +234,12 @@ static void BM_AcquireSpinlock(benchmark::State& state) { gpr_spinlock_unlock(&mu); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_AcquireSpinlock); static void BM_TryAcquireSpinlock(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; // for comparison with the combiner stuff below gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -281,11 +252,12 @@ static void BM_TryAcquireSpinlock(benchmark::State& state) { } } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_TryAcquireSpinlock); static void BM_ClosureSchedOnCombiner(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_combiner* combiner = grpc_combiner_create(NULL); grpc_closure c; grpc_closure_init(&c, DoNothing, NULL, @@ -297,11 +269,12 @@ static void BM_ClosureSchedOnCombiner(benchmark::State& state) { } GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSchedOnCombiner); static void BM_ClosureSched2OnCombiner(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_combiner* combiner = grpc_combiner_create(NULL); grpc_closure c1; grpc_closure c2; @@ -317,11 +290,12 @@ static void BM_ClosureSched2OnCombiner(benchmark::State& state) { } GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSched2OnCombiner); static void BM_ClosureSched3OnCombiner(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_combiner* combiner = grpc_combiner_create(NULL); grpc_closure c1; grpc_closure c2; @@ -341,11 +315,12 @@ static void BM_ClosureSched3OnCombiner(benchmark::State& state) { } GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSched3OnCombiner); static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_combiner* combiner1 = grpc_combiner_create(NULL); grpc_combiner* combiner2 = grpc_combiner_create(NULL); grpc_closure c1; @@ -363,11 +338,12 @@ static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) { GRPC_COMBINER_UNREF(&exec_ctx, combiner1, "finished"); GRPC_COMBINER_UNREF(&exec_ctx, combiner2, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSched2OnTwoCombiners); static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_combiner* combiner1 = grpc_combiner_create(NULL); grpc_combiner* combiner2 = grpc_combiner_create(NULL); grpc_closure c1; @@ -393,6 +369,7 @@ static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) { GRPC_COMBINER_UNREF(&exec_ctx, combiner1, "finished"); GRPC_COMBINER_UNREF(&exec_ctx, combiner2, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureSched4OnTwoCombiners); @@ -428,16 +405,17 @@ class Rescheduler { }; static void BM_ClosureReschedOnExecCtx(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; Rescheduler r(state, grpc_schedule_on_exec_ctx); r.ScheduleFirst(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureReschedOnExecCtx); static void BM_ClosureReschedOnCombiner(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_combiner* combiner = grpc_combiner_create(NULL); Rescheduler r(state, grpc_combiner_scheduler(combiner, false)); @@ -445,11 +423,12 @@ static void BM_ClosureReschedOnCombiner(benchmark::State& state) { grpc_exec_ctx_flush(&exec_ctx); GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureReschedOnCombiner); static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) { - TrackCounters track_counters(state); + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_combiner* combiner = grpc_combiner_create(NULL); Rescheduler r(state, grpc_combiner_finally_scheduler(combiner, false)); @@ -458,6 +437,7 @@ static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) { grpc_exec_ctx_flush(&exec_ctx); GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished"); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_ClosureReschedOnCombinerFinally); diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index c017474bf4a..91e6a851017 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -38,6 +38,7 @@ #include #include +#include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" extern "C" { @@ -47,27 +48,23 @@ extern "C" { namespace grpc { namespace testing { -static class InitializeStuff { - public: - InitializeStuff() { init_lib_.init(); } - ~InitializeStuff() { init_lib_.shutdown(); } - - private: - internal::GrpcLibrary init_lib_; - internal::GrpcLibraryInitializer init_; -} initialize_stuff; +auto& force_library_initialization = Library::get(); static void BM_CreateDestroyCpp(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { CompletionQueue cq; } + track_counters.Finish(state); } BENCHMARK(BM_CreateDestroyCpp); static void BM_CreateDestroyCore(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { grpc_completion_queue_destroy(grpc_completion_queue_create(NULL)); } + track_counters.Finish(state); } BENCHMARK(BM_CreateDestroyCore); @@ -80,6 +77,7 @@ class DummyTag final : public CompletionQueueTag { }; static void BM_Pass1Cpp(benchmark::State& state) { + TrackCounters track_counters; CompletionQueue cq; grpc_completion_queue* c_cq = cq.cq(); while (state.KeepRunning()) { @@ -94,10 +92,12 @@ static void BM_Pass1Cpp(benchmark::State& state) { bool ok; cq.Next(&tag, &ok); } + track_counters.Finish(state); } BENCHMARK(BM_Pass1Cpp); static void BM_Pass1Core(benchmark::State& state) { + TrackCounters track_counters; grpc_completion_queue* cq = grpc_completion_queue_create(NULL); gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); while (state.KeepRunning()) { @@ -110,10 +110,12 @@ static void BM_Pass1Core(benchmark::State& state) { grpc_completion_queue_next(cq, deadline, NULL); } grpc_completion_queue_destroy(cq); + track_counters.Finish(state); } BENCHMARK(BM_Pass1Core); static void BM_Pluck1Core(benchmark::State& state) { + TrackCounters track_counters; grpc_completion_queue* cq = grpc_completion_queue_create(NULL); gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); while (state.KeepRunning()) { @@ -126,16 +128,19 @@ static void BM_Pluck1Core(benchmark::State& state) { grpc_completion_queue_pluck(cq, NULL, deadline, NULL); } grpc_completion_queue_destroy(cq); + track_counters.Finish(state); } BENCHMARK(BM_Pluck1Core); static void BM_EmptyCore(benchmark::State& state) { + TrackCounters track_counters; grpc_completion_queue* cq = grpc_completion_queue_create(NULL); gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC); while (state.KeepRunning()) { grpc_completion_queue_next(cq, deadline, NULL); } grpc_completion_queue_destroy(cq); + track_counters.Finish(state); } BENCHMARK(BM_EmptyCore); diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index 8a4b86f281a..ff1519b1f4e 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -40,8 +40,11 @@ extern "C" { #include "src/core/lib/transport/error_utils.h" } +#include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" +auto& force_library_initialization = Library::get(); + class ErrorDeleter { public: void operator()(grpc_error* error) { GRPC_ERROR_UNREF(error); } @@ -49,31 +52,68 @@ class ErrorDeleter { typedef std::unique_ptr ErrorPtr; static void BM_ErrorCreate(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { GRPC_ERROR_UNREF(GRPC_ERROR_CREATE("Error")); } + track_counters.Finish(state); } BENCHMARK(BM_ErrorCreate); static void BM_ErrorCreateAndSetStatus(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { GRPC_ERROR_UNREF(grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_ABORTED)); } + track_counters.Finish(state); } BENCHMARK(BM_ErrorCreateAndSetStatus); +static void BM_ErrorCreateAndSetIntAndStr(benchmark::State& state) { + while (state.KeepRunning()) { + GRPC_ERROR_UNREF(grpc_error_set_str( + grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"), + GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)0), + GRPC_ERROR_STR_RAW_BYTES, "raw bytes")); + } +} +BENCHMARK(BM_ErrorCreateAndSetIntAndStr); + +static void BM_ErrorCreateAndSetIntLoop(benchmark::State& state) { + grpc_error* error = GRPC_ERROR_CREATE("Error"); + int n = 0; + while (state.KeepRunning()) { + error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, n++); + } + GRPC_ERROR_UNREF(error); +} +BENCHMARK(BM_ErrorCreateAndSetIntLoop); + +static void BM_ErrorCreateAndSetStrLoop(benchmark::State& state) { + grpc_error* error = GRPC_ERROR_CREATE("Error"); + const char* str = "hello"; + while (state.KeepRunning()) { + error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, str); + } + GRPC_ERROR_UNREF(error); +} +BENCHMARK(BM_ErrorCreateAndSetStrLoop); + static void BM_ErrorRefUnref(benchmark::State& state) { + TrackCounters track_counters; grpc_error* error = GRPC_ERROR_CREATE("Error"); while (state.KeepRunning()) { GRPC_ERROR_UNREF(GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); + track_counters.Finish(state); } BENCHMARK(BM_ErrorRefUnref); static void BM_ErrorUnrefNone(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { GRPC_ERROR_UNREF(GRPC_ERROR_NONE); } @@ -81,30 +121,36 @@ static void BM_ErrorUnrefNone(benchmark::State& state) { BENCHMARK(BM_ErrorUnrefNone); static void BM_ErrorGetIntFromNoError(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { intptr_t value; grpc_error_get_int(GRPC_ERROR_NONE, GRPC_ERROR_INT_GRPC_STATUS, &value); } + track_counters.Finish(state); } BENCHMARK(BM_ErrorGetIntFromNoError); static void BM_ErrorGetMissingInt(benchmark::State& state) { + TrackCounters track_counters; ErrorPtr error( grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_INDEX, 1)); while (state.KeepRunning()) { intptr_t value; grpc_error_get_int(error.get(), GRPC_ERROR_INT_OFFSET, &value); } + track_counters.Finish(state); } BENCHMARK(BM_ErrorGetMissingInt); static void BM_ErrorGetPresentInt(benchmark::State& state) { + TrackCounters track_counters; ErrorPtr error( grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_OFFSET, 1)); while (state.KeepRunning()) { intptr_t value; grpc_error_get_int(error.get(), GRPC_ERROR_INT_OFFSET, &value); } + track_counters.Finish(state); } BENCHMARK(BM_ErrorGetPresentInt); @@ -177,22 +223,27 @@ class ErrorWithNestedGrpcStatus { template static void BM_ErrorStringOnNewError(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { Fixture fixture; grpc_error_string(fixture.error()); } + track_counters.Finish(state); } template static void BM_ErrorStringRepeatedly(benchmark::State& state) { + TrackCounters track_counters; Fixture fixture; while (state.KeepRunning()) { grpc_error_string(fixture.error()); } + track_counters.Finish(state); } template static void BM_ErrorGetStatus(benchmark::State& state) { + TrackCounters track_counters; Fixture fixture; while (state.KeepRunning()) { grpc_status_code status; @@ -200,34 +251,41 @@ static void BM_ErrorGetStatus(benchmark::State& state) { grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &msg, NULL); } + track_counters.Finish(state); } template static void BM_ErrorGetStatusCode(benchmark::State& state) { + TrackCounters track_counters; Fixture fixture; while (state.KeepRunning()) { grpc_status_code status; grpc_error_get_status(fixture.error(), fixture.deadline(), &status, NULL, NULL); } + track_counters.Finish(state); } template static void BM_ErrorHttpError(benchmark::State& state) { + TrackCounters track_counters; Fixture fixture; while (state.KeepRunning()) { grpc_http2_error_code error; grpc_error_get_status(fixture.error(), fixture.deadline(), NULL, NULL, &error); } + track_counters.Finish(state); } template static void BM_HasClearGrpcStatus(benchmark::State& state) { + TrackCounters track_counters; Fixture fixture; while (state.KeepRunning()) { grpc_error_has_clear_grpc_status(fixture.error()); } + track_counters.Finish(state); } #define BENCHMARK_SUITE(fixture) \ diff --git a/test/cpp/microbenchmarks/bm_fullstack.cc b/test/cpp/microbenchmarks/bm_fullstack.cc deleted file mode 100644 index 48e131f1be0..00000000000 --- a/test/cpp/microbenchmarks/bm_fullstack.cc +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* Benchmark gRPC end2end in various configurations */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" -#include "src/core/ext/transport/chttp2/transport/internal.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/endpoint_pair.h" -#include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/tcp_posix.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/surface/completion_queue.h" -#include "src/core/lib/surface/server.h" -#include "test/core/util/memory_counters.h" -#include "test/core/util/passthru_endpoint.h" -#include "test/core/util/port.h" -#include "test/core/util/trickle_endpoint.h" -} -#include "src/core/lib/profiling/timers.h" -#include "src/cpp/client/create_channel_internal.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "third_party/benchmark/include/benchmark/benchmark.h" - -namespace grpc { -namespace testing { - -static class InitializeStuff { - public: - InitializeStuff() { - grpc_memory_counters_init(); - init_lib_.init(); - rq_ = grpc_resource_quota_create("bm"); - } - - ~InitializeStuff() { init_lib_.shutdown(); } - - grpc_resource_quota* rq() { return rq_; } - - private: - internal::GrpcLibrary init_lib_; - grpc_resource_quota* rq_; -} initialize_stuff; - -/******************************************************************************* - * FIXTURES - */ - -static void ApplyCommonServerBuilderConfig(ServerBuilder* b) { - b->SetMaxReceiveMessageSize(INT_MAX); - b->SetMaxSendMessageSize(INT_MAX); -} - -static void ApplyCommonChannelArguments(ChannelArguments* c) { - c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX); - c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX); -} - -#ifdef GPR_LOW_LEVEL_COUNTERS -extern "C" gpr_atm gpr_mu_locks; -extern "C" gpr_atm gpr_counter_atm_cas; -extern "C" gpr_atm gpr_counter_atm_add; -#endif - -class BaseFixture { - public: - void Finish(benchmark::State& s) { - std::ostringstream out; - this->AddToLabel(out, s); -#ifdef GPR_LOW_LEVEL_COUNTERS - out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) - - mu_locks_at_start_) / - (double)s.iterations()) - << " atm_cas/iter:" - << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_cas) - - atm_cas_at_start_) / - (double)s.iterations()) - << " atm_add/iter:" - << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) - - atm_add_at_start_) / - (double)s.iterations()); -#endif - grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot(); - out << " allocs/iter:" - << ((double)(counters_at_end.total_allocs_absolute - - counters_at_start_.total_allocs_absolute) / - (double)s.iterations()); - auto label = out.str(); - if (label.length() && label[0] == ' ') { - label = label.substr(1); - } - s.SetLabel(label); - } - - virtual void AddToLabel(std::ostream& out, benchmark::State& s) = 0; - - private: -#ifdef GPR_LOW_LEVEL_COUNTERS - const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks); - const size_t atm_cas_at_start_ = - gpr_atm_no_barrier_load(&gpr_counter_atm_cas); - const size_t atm_add_at_start_ = - gpr_atm_no_barrier_load(&gpr_counter_atm_add); -#endif - grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot(); -}; - -class FullstackFixture : public BaseFixture { - public: - FullstackFixture(Service* service, const grpc::string& address) { - ServerBuilder b; - b.AddListeningPort(address, InsecureServerCredentials()); - cq_ = b.AddCompletionQueue(true); - b.RegisterService(service); - ApplyCommonServerBuilderConfig(&b); - server_ = b.BuildAndStart(); - ChannelArguments args; - ApplyCommonChannelArguments(&args); - channel_ = CreateCustomChannel(address, InsecureChannelCredentials(), args); - } - - virtual ~FullstackFixture() { - server_->Shutdown(); - cq_->Shutdown(); - void* tag; - bool ok; - while (cq_->Next(&tag, &ok)) { - } - } - - ServerCompletionQueue* cq() { return cq_.get(); } - std::shared_ptr channel() { return channel_; } - - private: - std::unique_ptr server_; - std::unique_ptr cq_; - std::shared_ptr channel_; -}; - -class TCP : public FullstackFixture { - public: - TCP(Service* service) : FullstackFixture(service, MakeAddress()) {} - - void AddToLabel(std::ostream& out, benchmark::State& state) {} - - private: - static grpc::string MakeAddress() { - int port = grpc_pick_unused_port_or_die(); - std::stringstream addr; - addr << "localhost:" << port; - return addr.str(); - } -}; - -class UDS : public FullstackFixture { - public: - UDS(Service* service) : FullstackFixture(service, MakeAddress()) {} - - void AddToLabel(std::ostream& out, benchmark::State& state) override {} - - private: - static grpc::string MakeAddress() { - int port = grpc_pick_unused_port_or_die(); // just for a unique id - not a - // real port - std::stringstream addr; - addr << "unix:/tmp/bm_fullstack." << port; - return addr.str(); - } -}; - -class EndpointPairFixture : public BaseFixture { - public: - EndpointPairFixture(Service* service, grpc_endpoint_pair endpoints) - : endpoint_pair_(endpoints) { - ServerBuilder b; - cq_ = b.AddCompletionQueue(true); - b.RegisterService(service); - ApplyCommonServerBuilderConfig(&b); - server_ = b.BuildAndStart(); - - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - /* add server endpoint to server_ */ - { - const grpc_channel_args* server_args = - grpc_server_get_channel_args(server_->c_server()); - server_transport_ = grpc_create_chttp2_transport( - &exec_ctx, server_args, endpoints.server, 0 /* is_client */); - - grpc_pollset** pollsets; - size_t num_pollsets = 0; - grpc_server_get_pollsets(server_->c_server(), &pollsets, &num_pollsets); - - for (size_t i = 0; i < num_pollsets; i++) { - grpc_endpoint_add_to_pollset(&exec_ctx, endpoints.server, pollsets[i]); - } - - grpc_server_setup_transport(&exec_ctx, server_->c_server(), - server_transport_, NULL, server_args); - grpc_chttp2_transport_start_reading(&exec_ctx, server_transport_, NULL); - } - - /* create channel */ - { - ChannelArguments args; - args.SetString(GRPC_ARG_DEFAULT_AUTHORITY, "test.authority"); - ApplyCommonChannelArguments(&args); - - grpc_channel_args c_args = args.c_channel_args(); - client_transport_ = - grpc_create_chttp2_transport(&exec_ctx, &c_args, endpoints.client, 1); - GPR_ASSERT(client_transport_); - grpc_channel* channel = - grpc_channel_create(&exec_ctx, "target", &c_args, - GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); - grpc_chttp2_transport_start_reading(&exec_ctx, client_transport_, NULL); - - channel_ = CreateChannelInternal("", channel); - } - - grpc_exec_ctx_finish(&exec_ctx); - } - - virtual ~EndpointPairFixture() { - server_->Shutdown(); - cq_->Shutdown(); - void* tag; - bool ok; - while (cq_->Next(&tag, &ok)) { - } - } - - ServerCompletionQueue* cq() { return cq_.get(); } - std::shared_ptr channel() { return channel_; } - - protected: - grpc_endpoint_pair endpoint_pair_; - grpc_transport* client_transport_; - grpc_transport* server_transport_; - - private: - std::unique_ptr server_; - std::unique_ptr cq_; - std::shared_ptr channel_; -}; - -class SockPair : public EndpointPairFixture { - public: - SockPair(Service* service) - : EndpointPairFixture(service, grpc_iomgr_create_endpoint_pair( - "test", initialize_stuff.rq(), 8192)) { - } - - void AddToLabel(std::ostream& out, benchmark::State& state) {} -}; - -class InProcessCHTTP2 : public EndpointPairFixture { - public: - InProcessCHTTP2(Service* service) - : EndpointPairFixture(service, MakeEndpoints()) {} - - void AddToLabel(std::ostream& out, benchmark::State& state) { - out << " writes/iter:" - << ((double)stats_.num_writes / (double)state.iterations()); - } - - private: - grpc_passthru_endpoint_stats stats_; - - grpc_endpoint_pair MakeEndpoints() { - grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, initialize_stuff.rq(), - &stats_); - return p; - } -}; - -class TrickledCHTTP2 : public EndpointPairFixture { - public: - TrickledCHTTP2(Service* service, size_t megabits_per_second) - : EndpointPairFixture(service, MakeEndpoints(megabits_per_second)) {} - - void AddToLabel(std::ostream& out, benchmark::State& state) { - out << " writes/iter:" - << ((double)stats_.num_writes / (double)state.iterations()) - << " cli_transport_stalls/iter:" - << ((double) - client_stats_.streams_stalled_due_to_transport_flow_control / - (double)state.iterations()) - << " cli_stream_stalls/iter:" - << ((double)client_stats_.streams_stalled_due_to_stream_flow_control / - (double)state.iterations()) - << " svr_transport_stalls/iter:" - << ((double) - server_stats_.streams_stalled_due_to_transport_flow_control / - (double)state.iterations()) - << " svr_stream_stalls/iter:" - << ((double)server_stats_.streams_stalled_due_to_stream_flow_control / - (double)state.iterations()); - } - - void Step() { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - size_t client_backlog = - grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.client); - size_t server_backlog = - grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.server); - grpc_exec_ctx_finish(&exec_ctx); - - UpdateStats((grpc_chttp2_transport*)client_transport_, &client_stats_, - client_backlog); - UpdateStats((grpc_chttp2_transport*)server_transport_, &server_stats_, - server_backlog); - } - - private: - grpc_passthru_endpoint_stats stats_; - struct Stats { - int streams_stalled_due_to_stream_flow_control = 0; - int streams_stalled_due_to_transport_flow_control = 0; - }; - Stats client_stats_; - Stats server_stats_; - - grpc_endpoint_pair MakeEndpoints(size_t kilobits) { - grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, initialize_stuff.rq(), - &stats_); - double bytes_per_second = 125.0 * kilobits; - p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second); - p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second); - return p; - } - - void UpdateStats(grpc_chttp2_transport* t, Stats* s, size_t backlog) { - if (backlog == 0) { - if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != NULL) { - s->streams_stalled_due_to_stream_flow_control++; - } - if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != NULL) { - s->streams_stalled_due_to_transport_flow_control++; - } - } - } -}; - -/******************************************************************************* - * CONTEXT MUTATORS - */ - -static const int kPregenerateKeyCount = 100000; - -template -auto MakeVector(size_t length, F f) -> std::vector { - std::vector out; - out.reserve(length); - for (size_t i = 0; i < length; i++) { - out.push_back(f()); - } - return out; -} - -class NoOpMutator { - public: - template - NoOpMutator(ContextType* context) {} -}; - -template -class RandomBinaryMetadata { - public: - static const grpc::string& Key() { return kKey; } - - static const grpc::string& Value() { - return kValues[rand() % kValues.size()]; - } - - private: - static const grpc::string kKey; - static const std::vector kValues; - - static grpc::string GenerateOneString() { - grpc::string s; - s.reserve(length + 1); - for (int i = 0; i < length; i++) { - s += (char)rand(); - } - return s; - } -}; - -template -const grpc::string RandomBinaryMetadata::kKey = "foo-bin"; - -template -const std::vector RandomBinaryMetadata::kValues = - MakeVector(kPregenerateKeyCount, GenerateOneString); - -template -class RandomAsciiMetadata { - public: - static const grpc::string& Key() { return kKey; } - - static const grpc::string& Value() { - return kValues[rand() % kValues.size()]; - } - - private: - static const grpc::string kKey; - static const std::vector kValues; - - static grpc::string GenerateOneString() { - grpc::string s; - s.reserve(length + 1); - for (int i = 0; i < length; i++) { - s += (char)(rand() % 26 + 'a'); - } - return s; - } -}; - -template -const grpc::string RandomAsciiMetadata::kKey = "foo"; - -template -const std::vector RandomAsciiMetadata::kValues = - MakeVector(kPregenerateKeyCount, GenerateOneString); - -template -class Client_AddMetadata : public NoOpMutator { - public: - Client_AddMetadata(ClientContext* context) : NoOpMutator(context) { - for (int i = 0; i < kNumKeys; i++) { - context->AddMetadata(Generator::Key(), Generator::Value()); - } - } -}; - -template -class Server_AddInitialMetadata : public NoOpMutator { - public: - Server_AddInitialMetadata(ServerContext* context) : NoOpMutator(context) { - for (int i = 0; i < kNumKeys; i++) { - context->AddInitialMetadata(Generator::Key(), Generator::Value()); - } - } -}; - -/******************************************************************************* - * BENCHMARKING KERNELS - */ - -static void* tag(intptr_t x) { return reinterpret_cast(x); } - -template -static void BM_UnaryPingPong(benchmark::State& state) { - EchoTestService::AsyncService service; - std::unique_ptr fixture(new Fixture(&service)); - EchoRequest send_request; - EchoResponse send_response; - EchoResponse recv_response; - if (state.range(0) > 0) { - send_request.set_message(std::string(state.range(0), 'a')); - } - if (state.range(1) > 0) { - send_response.set_message(std::string(state.range(1), 'a')); - } - Status recv_status; - struct ServerEnv { - ServerContext ctx; - EchoRequest recv_request; - grpc::ServerAsyncResponseWriter response_writer; - ServerEnv() : response_writer(&ctx) {} - }; - uint8_t server_env_buffer[2 * sizeof(ServerEnv)]; - ServerEnv* server_env[2] = { - reinterpret_cast(server_env_buffer), - reinterpret_cast(server_env_buffer + sizeof(ServerEnv))}; - new (server_env[0]) ServerEnv; - new (server_env[1]) ServerEnv; - service.RequestEcho(&server_env[0]->ctx, &server_env[0]->recv_request, - &server_env[0]->response_writer, fixture->cq(), - fixture->cq(), tag(0)); - service.RequestEcho(&server_env[1]->ctx, &server_env[1]->recv_request, - &server_env[1]->response_writer, fixture->cq(), - fixture->cq(), tag(1)); - std::unique_ptr stub( - EchoTestService::NewStub(fixture->channel())); - while (state.KeepRunning()) { - GPR_TIMER_SCOPE("BenchmarkCycle", 0); - recv_response.Clear(); - ClientContext cli_ctx; - ClientContextMutator cli_ctx_mut(&cli_ctx); - std::unique_ptr> response_reader( - stub->AsyncEcho(&cli_ctx, send_request, fixture->cq())); - void* t; - bool ok; - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - GPR_ASSERT(t == tag(0) || t == tag(1)); - intptr_t slot = reinterpret_cast(t); - ServerEnv* senv = server_env[slot]; - ServerContextMutator svr_ctx_mut(&senv->ctx); - senv->response_writer.Finish(send_response, Status::OK, tag(3)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - for (int i = (1 << 3) | (1 << 4); i != 0;) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int tagnum = (int)reinterpret_cast(t); - GPR_ASSERT(i & (1 << tagnum)); - i -= 1 << tagnum; - } - GPR_ASSERT(recv_status.ok()); - - senv->~ServerEnv(); - senv = new (senv) ServerEnv(); - service.RequestEcho(&senv->ctx, &senv->recv_request, &senv->response_writer, - fixture->cq(), fixture->cq(), tag(slot)); - } - fixture->Finish(state); - fixture.reset(); - server_env[0]->~ServerEnv(); - server_env[1]->~ServerEnv(); - state.SetBytesProcessed(state.range(0) * state.iterations() + - state.range(1) * state.iterations()); -} - -// Repeatedly makes Streaming Bidi calls (exchanging a configurable number of -// messages in each call) in a loop on a single channel -// -// First parmeter (i.e state.range(0)): Message size (in bytes) to use -// Second parameter (i.e state.range(1)): Number of ping pong messages. -// Note: One ping-pong means two messages (one from client to server and -// the other from server to client): -template -static void BM_StreamingPingPong(benchmark::State& state) { - const int msg_size = state.range(0); - const int max_ping_pongs = state.range(1); - - EchoTestService::AsyncService service; - std::unique_ptr fixture(new Fixture(&service)); - { - EchoResponse send_response; - EchoResponse recv_response; - EchoRequest send_request; - EchoRequest recv_request; - - if (msg_size > 0) { - send_request.set_message(std::string(msg_size, 'a')); - send_response.set_message(std::string(msg_size, 'b')); - } - - std::unique_ptr stub( - EchoTestService::NewStub(fixture->channel())); - - while (state.KeepRunning()) { - ServerContext svr_ctx; - ServerContextMutator svr_ctx_mut(&svr_ctx); - ServerAsyncReaderWriter response_rw(&svr_ctx); - service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), - fixture->cq(), tag(0)); - - ClientContext cli_ctx; - ClientContextMutator cli_ctx_mut(&cli_ctx); - auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); - - // Establish async stream between client side and server side - void* t; - bool ok; - int need_tags = (1 << 0) | (1 << 1); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - - // Send 'max_ping_pongs' number of ping pong messages - int ping_pong_cnt = 0; - while (ping_pong_cnt < max_ping_pongs) { - request_rw->Write(send_request, tag(0)); // Start client send - response_rw.Read(&recv_request, tag(1)); // Start server recv - request_rw->Read(&recv_response, tag(2)); // Start client recv - - need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - - // If server recv is complete, start the server send operation - if (i == 1) { - response_rw.Write(send_response, tag(3)); - } - - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - - ping_pong_cnt++; - } - - request_rw->WritesDone(tag(0)); - response_rw.Finish(Status::OK, tag(1)); - - Status recv_status; - request_rw->Finish(&recv_status, tag(2)); - - need_tags = (1 << 0) | (1 << 1) | (1 << 2); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - - GPR_ASSERT(recv_status.ok()); - } - } - - fixture->Finish(state); - fixture.reset(); - state.SetBytesProcessed(msg_size * state.iterations() * max_ping_pongs * 2); -} - -// Repeatedly sends ping pong messages in a single streaming Bidi call in a loop -// First parmeter (i.e state.range(0)): Message size (in bytes) to use -template -static void BM_StreamingPingPongMsgs(benchmark::State& state) { - const int msg_size = state.range(0); - - EchoTestService::AsyncService service; - std::unique_ptr fixture(new Fixture(&service)); - { - EchoResponse send_response; - EchoResponse recv_response; - EchoRequest send_request; - EchoRequest recv_request; - - if (msg_size > 0) { - send_request.set_message(std::string(msg_size, 'a')); - send_response.set_message(std::string(msg_size, 'b')); - } - - std::unique_ptr stub( - EchoTestService::NewStub(fixture->channel())); - - ServerContext svr_ctx; - ServerContextMutator svr_ctx_mut(&svr_ctx); - ServerAsyncReaderWriter response_rw(&svr_ctx); - service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), - fixture->cq(), tag(0)); - - ClientContext cli_ctx; - ClientContextMutator cli_ctx_mut(&cli_ctx); - auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); - - // Establish async stream between client side and server side - void* t; - bool ok; - int need_tags = (1 << 0) | (1 << 1); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - - while (state.KeepRunning()) { - GPR_TIMER_SCOPE("BenchmarkCycle", 0); - request_rw->Write(send_request, tag(0)); // Start client send - response_rw.Read(&recv_request, tag(1)); // Start server recv - request_rw->Read(&recv_response, tag(2)); // Start client recv - - need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - - // If server recv is complete, start the server send operation - if (i == 1) { - response_rw.Write(send_response, tag(3)); - } - - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - } - - request_rw->WritesDone(tag(0)); - response_rw.Finish(Status::OK, tag(1)); - Status recv_status; - request_rw->Finish(&recv_status, tag(2)); - - need_tags = (1 << 0) | (1 << 1) | (1 << 2); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - - GPR_ASSERT(recv_status.ok()); - } - - fixture->Finish(state); - fixture.reset(); - state.SetBytesProcessed(msg_size * state.iterations() * 2); -} - -template -static void BM_PumpStreamClientToServer(benchmark::State& state) { - EchoTestService::AsyncService service; - std::unique_ptr fixture(new Fixture(&service)); - { - EchoRequest send_request; - EchoRequest recv_request; - if (state.range(0) > 0) { - send_request.set_message(std::string(state.range(0), 'a')); - } - Status recv_status; - ServerContext svr_ctx; - ServerAsyncReaderWriter response_rw(&svr_ctx); - service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), - fixture->cq(), tag(0)); - std::unique_ptr stub( - EchoTestService::NewStub(fixture->channel())); - ClientContext cli_ctx; - auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); - int need_tags = (1 << 0) | (1 << 1); - void* t; - bool ok; - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - response_rw.Read(&recv_request, tag(0)); - while (state.KeepRunning()) { - GPR_TIMER_SCOPE("BenchmarkCycle", 0); - request_rw->Write(send_request, tag(1)); - while (true) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - if (t == tag(0)) { - response_rw.Read(&recv_request, tag(0)); - } else if (t == tag(1)) { - break; - } else { - GPR_ASSERT(false); - } - } - } - request_rw->WritesDone(tag(1)); - need_tags = (1 << 0) | (1 << 1); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - } - fixture->Finish(state); - fixture.reset(); - state.SetBytesProcessed(state.range(0) * state.iterations()); -} - -template -static void BM_PumpStreamServerToClient(benchmark::State& state) { - EchoTestService::AsyncService service; - std::unique_ptr fixture(new Fixture(&service)); - { - EchoResponse send_response; - EchoResponse recv_response; - if (state.range(0) > 0) { - send_response.set_message(std::string(state.range(0), 'a')); - } - Status recv_status; - ServerContext svr_ctx; - ServerAsyncReaderWriter response_rw(&svr_ctx); - service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), - fixture->cq(), tag(0)); - std::unique_ptr stub( - EchoTestService::NewStub(fixture->channel())); - ClientContext cli_ctx; - auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); - int need_tags = (1 << 0) | (1 << 1); - void* t; - bool ok; - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - request_rw->Read(&recv_response, tag(0)); - while (state.KeepRunning()) { - GPR_TIMER_SCOPE("BenchmarkCycle", 0); - response_rw.Write(send_response, tag(1)); - while (true) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - if (t == tag(0)) { - request_rw->Read(&recv_response, tag(0)); - } else if (t == tag(1)) { - break; - } else { - GPR_ASSERT(false); - } - } - } - response_rw.Finish(Status::OK, tag(1)); - need_tags = (1 << 0) | (1 << 1); - while (need_tags) { - GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - } - fixture->Finish(state); - fixture.reset(); - state.SetBytesProcessed(state.range(0) * state.iterations()); -} - -static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok) { - while (true) { - switch (fixture->cq()->AsyncNext( - t, ok, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(100, GPR_TIMESPAN)))) { - case CompletionQueue::TIMEOUT: - fixture->Step(); - break; - case CompletionQueue::SHUTDOWN: - GPR_ASSERT(false); - break; - case CompletionQueue::GOT_EVENT: - return; - } - } -} - -static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) { - EchoTestService::AsyncService service; - std::unique_ptr fixture( - new TrickledCHTTP2(&service, state.range(1))); - { - EchoResponse send_response; - EchoResponse recv_response; - if (state.range(0) > 0) { - send_response.set_message(std::string(state.range(0), 'a')); - } - Status recv_status; - ServerContext svr_ctx; - ServerAsyncReaderWriter response_rw(&svr_ctx); - service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), - fixture->cq(), tag(0)); - std::unique_ptr stub( - EchoTestService::NewStub(fixture->channel())); - ClientContext cli_ctx; - auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); - int need_tags = (1 << 0) | (1 << 1); - void* t; - bool ok; - while (need_tags) { - TrickleCQNext(fixture.get(), &t, &ok); - GPR_ASSERT(ok); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - request_rw->Read(&recv_response, tag(0)); - while (state.KeepRunning()) { - GPR_TIMER_SCOPE("BenchmarkCycle", 0); - response_rw.Write(send_response, tag(1)); - while (true) { - TrickleCQNext(fixture.get(), &t, &ok); - if (t == tag(0)) { - request_rw->Read(&recv_response, tag(0)); - } else if (t == tag(1)) { - break; - } else { - GPR_ASSERT(false); - } - } - } - response_rw.Finish(Status::OK, tag(1)); - need_tags = (1 << 0) | (1 << 1); - while (need_tags) { - TrickleCQNext(fixture.get(), &t, &ok); - int i = (int)(intptr_t)t; - GPR_ASSERT(need_tags & (1 << i)); - need_tags &= ~(1 << i); - } - } - fixture->Finish(state); - fixture.reset(); - state.SetBytesProcessed(state.range(0) * state.iterations()); -} - -/******************************************************************************* - * CONFIGURATIONS - */ - -static void SweepSizesArgs(benchmark::internal::Benchmark* b) { - b->Args({0, 0}); - for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { - b->Args({i, 0}); - b->Args({0, i}); - b->Args({i, i}); - } -} - -BENCHMARK_TEMPLATE(BM_UnaryPingPong, TCP, NoOpMutator, NoOpMutator) - ->Apply(SweepSizesArgs); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, UDS, NoOpMutator, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, SockPair, NoOpMutator, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, NoOpMutator) - ->Apply(SweepSizesArgs); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, - NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, - NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 100>) - ->Args({0, 0}); - -BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, SockPair) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, InProcessCHTTP2) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, TCP) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, UDS) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, SockPair) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, InProcessCHTTP2) - ->Range(0, 128 * 1024 * 1024); - -static void TrickleArgs(benchmark::internal::Benchmark* b) { - for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { - for (int j = 1; j <= 128 * 1024 * 1024; j *= 8) { - double expected_time = - static_cast(14 + i) / (125.0 * static_cast(j)); - if (expected_time > 0.01) continue; - b->Args({i, j}); - } - } -} - -BENCHMARK(BM_PumpStreamServerToClient_Trickle)->Apply(TrickleArgs); - -// Generate Args for StreamingPingPong benchmarks. Currently generates args for -// only "small streams" (i.e streams with 0, 1 or 2 messages) -static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) { - int msg_size = 0; - - b->Args({0, 0}); // spl case: 0 ping-pong msgs (msg_size doesn't matter here) - - for (msg_size = 0; msg_size <= 128 * 1024 * 1024; - msg_size == 0 ? msg_size++ : msg_size *= 8) { - b->Args({msg_size, 1}); - b->Args({msg_size, 2}); - } -} - -BENCHMARK_TEMPLATE(BM_StreamingPingPong, InProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(StreamingPingPongArgs); -BENCHMARK_TEMPLATE(BM_StreamingPingPong, TCP, NoOpMutator, NoOpMutator) - ->Apply(StreamingPingPongArgs); - -BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, InProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Range(0, 128 * 1024 * 1024); -BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, TCP, NoOpMutator, NoOpMutator) - ->Range(0, 128 * 1024 * 1024); - -} // namespace testing -} // namespace grpc - -BENCHMARK_MAIN(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc new file mode 100644 index 00000000000..dc0e7d769ab --- /dev/null +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc @@ -0,0 +1,197 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Benchmark gRPC end2end in various configurations */ + +#include + +#include "src/core/lib/profiling/timers.h" +#include "src/cpp/client/create_channel_internal.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" +#include "third_party/benchmark/include/benchmark/benchmark.h" + +namespace grpc { +namespace testing { + +// force library initialization +auto& force_library_initialization = Library::get(); + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +static void* tag(intptr_t x) { return reinterpret_cast(x); } + +template +static void BM_PumpStreamClientToServer(benchmark::State& state) { + EchoTestService::AsyncService service; + std::unique_ptr fixture(new Fixture(&service)); + { + EchoRequest send_request; + EchoRequest recv_request; + if (state.range(0) > 0) { + send_request.set_message(std::string(state.range(0), 'a')); + } + Status recv_status; + ServerContext svr_ctx; + ServerAsyncReaderWriter response_rw(&svr_ctx); + service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), + fixture->cq(), tag(0)); + std::unique_ptr stub( + EchoTestService::NewStub(fixture->channel())); + ClientContext cli_ctx; + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + int need_tags = (1 << 0) | (1 << 1); + void* t; + bool ok; + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + response_rw.Read(&recv_request, tag(0)); + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + request_rw->Write(send_request, tag(1)); + while (true) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + if (t == tag(0)) { + response_rw.Read(&recv_request, tag(0)); + } else if (t == tag(1)) { + break; + } else { + GPR_ASSERT(false); + } + } + } + request_rw->WritesDone(tag(1)); + need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(state.range(0) * state.iterations()); +} + +template +static void BM_PumpStreamServerToClient(benchmark::State& state) { + EchoTestService::AsyncService service; + std::unique_ptr fixture(new Fixture(&service)); + { + EchoResponse send_response; + EchoResponse recv_response; + if (state.range(0) > 0) { + send_response.set_message(std::string(state.range(0), 'a')); + } + Status recv_status; + ServerContext svr_ctx; + ServerAsyncReaderWriter response_rw(&svr_ctx); + service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), + fixture->cq(), tag(0)); + std::unique_ptr stub( + EchoTestService::NewStub(fixture->channel())); + ClientContext cli_ctx; + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + int need_tags = (1 << 0) | (1 << 1); + void* t; + bool ok; + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + request_rw->Read(&recv_response, tag(0)); + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + response_rw.Write(send_response, tag(1)); + while (true) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + if (t == tag(0)) { + request_rw->Read(&recv_response, tag(0)); + } else if (t == tag(1)) { + break; + } else { + GPR_ASSERT(false); + } + } + } + response_rw.Finish(Status::OK, tag(1)); + need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(state.range(0) * state.iterations()); +} + +/******************************************************************************* + * CONFIGURATIONS + */ + +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, SockPair) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, InProcessCHTTP2) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, TCP) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, UDS) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, SockPair) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, InProcessCHTTP2) + ->Range(0, 128 * 1024 * 1024); + +} // namespace testing +} // namespace grpc + +BENCHMARK_MAIN(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc new file mode 100644 index 00000000000..dc0e7d769ab --- /dev/null +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc @@ -0,0 +1,197 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Benchmark gRPC end2end in various configurations */ + +#include + +#include "src/core/lib/profiling/timers.h" +#include "src/cpp/client/create_channel_internal.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" +#include "third_party/benchmark/include/benchmark/benchmark.h" + +namespace grpc { +namespace testing { + +// force library initialization +auto& force_library_initialization = Library::get(); + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +static void* tag(intptr_t x) { return reinterpret_cast(x); } + +template +static void BM_PumpStreamClientToServer(benchmark::State& state) { + EchoTestService::AsyncService service; + std::unique_ptr fixture(new Fixture(&service)); + { + EchoRequest send_request; + EchoRequest recv_request; + if (state.range(0) > 0) { + send_request.set_message(std::string(state.range(0), 'a')); + } + Status recv_status; + ServerContext svr_ctx; + ServerAsyncReaderWriter response_rw(&svr_ctx); + service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), + fixture->cq(), tag(0)); + std::unique_ptr stub( + EchoTestService::NewStub(fixture->channel())); + ClientContext cli_ctx; + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + int need_tags = (1 << 0) | (1 << 1); + void* t; + bool ok; + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + response_rw.Read(&recv_request, tag(0)); + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + request_rw->Write(send_request, tag(1)); + while (true) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + if (t == tag(0)) { + response_rw.Read(&recv_request, tag(0)); + } else if (t == tag(1)) { + break; + } else { + GPR_ASSERT(false); + } + } + } + request_rw->WritesDone(tag(1)); + need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(state.range(0) * state.iterations()); +} + +template +static void BM_PumpStreamServerToClient(benchmark::State& state) { + EchoTestService::AsyncService service; + std::unique_ptr fixture(new Fixture(&service)); + { + EchoResponse send_response; + EchoResponse recv_response; + if (state.range(0) > 0) { + send_response.set_message(std::string(state.range(0), 'a')); + } + Status recv_status; + ServerContext svr_ctx; + ServerAsyncReaderWriter response_rw(&svr_ctx); + service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), + fixture->cq(), tag(0)); + std::unique_ptr stub( + EchoTestService::NewStub(fixture->channel())); + ClientContext cli_ctx; + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + int need_tags = (1 << 0) | (1 << 1); + void* t; + bool ok; + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + request_rw->Read(&recv_response, tag(0)); + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + response_rw.Write(send_response, tag(1)); + while (true) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + if (t == tag(0)) { + request_rw->Read(&recv_response, tag(0)); + } else if (t == tag(1)) { + break; + } else { + GPR_ASSERT(false); + } + } + } + response_rw.Finish(Status::OK, tag(1)); + need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(state.range(0) * state.iterations()); +} + +/******************************************************************************* + * CONFIGURATIONS + */ + +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, SockPair) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, InProcessCHTTP2) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, TCP) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, UDS) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, SockPair) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, InProcessCHTTP2) + ->Range(0, 128 * 1024 * 1024); + +} // namespace testing +} // namespace grpc + +BENCHMARK_MAIN(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc new file mode 100644 index 00000000000..5011f06368e --- /dev/null +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -0,0 +1,219 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Benchmark gRPC end2end in various configurations */ + +#include "src/core/lib/profiling/timers.h" +#include "src/cpp/client/create_channel_internal.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" +#include "third_party/benchmark/include/benchmark/benchmark.h" +extern "C" { +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/ext/transport/chttp2/transport/internal.h" +#include "test/core/util/trickle_endpoint.h" +} + +namespace grpc { +namespace testing { + +static void* tag(intptr_t x) { return reinterpret_cast(x); } + +class TrickledCHTTP2 : public EndpointPairFixture { + public: + TrickledCHTTP2(Service* service, size_t megabits_per_second) + : EndpointPairFixture(service, MakeEndpoints(megabits_per_second)) {} + + void AddToLabel(std::ostream& out, benchmark::State& state) { + out << " writes/iter:" + << ((double)stats_.num_writes / (double)state.iterations()) + << " cli_transport_stalls/iter:" + << ((double) + client_stats_.streams_stalled_due_to_transport_flow_control / + (double)state.iterations()) + << " cli_stream_stalls/iter:" + << ((double)client_stats_.streams_stalled_due_to_stream_flow_control / + (double)state.iterations()) + << " svr_transport_stalls/iter:" + << ((double) + server_stats_.streams_stalled_due_to_transport_flow_control / + (double)state.iterations()) + << " svr_stream_stalls/iter:" + << ((double)server_stats_.streams_stalled_due_to_stream_flow_control / + (double)state.iterations()); + } + + void Step() { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + size_t client_backlog = + grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.client); + size_t server_backlog = + grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.server); + grpc_exec_ctx_finish(&exec_ctx); + + UpdateStats((grpc_chttp2_transport*)client_transport_, &client_stats_, + client_backlog); + UpdateStats((grpc_chttp2_transport*)server_transport_, &server_stats_, + server_backlog); + } + + private: + grpc_passthru_endpoint_stats stats_; + struct Stats { + int streams_stalled_due_to_stream_flow_control = 0; + int streams_stalled_due_to_transport_flow_control = 0; + }; + Stats client_stats_; + Stats server_stats_; + + grpc_endpoint_pair MakeEndpoints(size_t kilobits) { + grpc_endpoint_pair p; + grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), + &stats_); + double bytes_per_second = 125.0 * kilobits; + p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second); + p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second); + return p; + } + + void UpdateStats(grpc_chttp2_transport* t, Stats* s, size_t backlog) { + if (backlog == 0) { + if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != NULL) { + s->streams_stalled_due_to_stream_flow_control++; + } + if (t->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != NULL) { + s->streams_stalled_due_to_transport_flow_control++; + } + } + } +}; + +// force library initialization +auto& force_library_initialization = Library::get(); + +static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok) { + while (true) { + switch (fixture->cq()->AsyncNext( + t, ok, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_micros(100, GPR_TIMESPAN)))) { + case CompletionQueue::TIMEOUT: + fixture->Step(); + break; + case CompletionQueue::SHUTDOWN: + GPR_ASSERT(false); + break; + case CompletionQueue::GOT_EVENT: + return; + } + } +} + +static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) { + EchoTestService::AsyncService service; + std::unique_ptr fixture( + new TrickledCHTTP2(&service, state.range(1))); + { + EchoResponse send_response; + EchoResponse recv_response; + if (state.range(0) > 0) { + send_response.set_message(std::string(state.range(0), 'a')); + } + Status recv_status; + ServerContext svr_ctx; + ServerAsyncReaderWriter response_rw(&svr_ctx); + service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(), + fixture->cq(), tag(0)); + std::unique_ptr stub( + EchoTestService::NewStub(fixture->channel())); + ClientContext cli_ctx; + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + int need_tags = (1 << 0) | (1 << 1); + void* t; + bool ok; + while (need_tags) { + TrickleCQNext(fixture.get(), &t, &ok); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + request_rw->Read(&recv_response, tag(0)); + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + response_rw.Write(send_response, tag(1)); + while (true) { + TrickleCQNext(fixture.get(), &t, &ok); + if (t == tag(0)) { + request_rw->Read(&recv_response, tag(0)); + } else if (t == tag(1)) { + break; + } else { + GPR_ASSERT(false); + } + } + } + response_rw.Finish(Status::OK, tag(1)); + need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + TrickleCQNext(fixture.get(), &t, &ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(state.range(0) * state.iterations()); +} + +/******************************************************************************* + * CONFIGURATIONS + */ + +static void TrickleArgs(benchmark::internal::Benchmark* b) { + for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { + for (int j = 1; j <= 128 * 1024 * 1024; j *= 8) { + double expected_time = + static_cast(14 + i) / (125.0 * static_cast(j)); + if (expected_time > 0.01) continue; + b->Args({i, j}); + } + } +} + +BENCHMARK(BM_PumpStreamServerToClient_Trickle)->Apply(TrickleArgs); +} +} + +BENCHMARK_MAIN(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc new file mode 100644 index 00000000000..e51d272b104 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc @@ -0,0 +1,205 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Benchmark gRPC end2end in various configurations */ + +#include + +#include "src/core/lib/profiling/timers.h" +#include "src/cpp/client/create_channel_internal.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" +#include "third_party/benchmark/include/benchmark/benchmark.h" + +namespace grpc { +namespace testing { + +// force library initialization +auto& force_library_initialization = Library::get(); + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +static void* tag(intptr_t x) { return reinterpret_cast(x); } + +template +static void BM_UnaryPingPong(benchmark::State& state) { + EchoTestService::AsyncService service; + std::unique_ptr fixture(new Fixture(&service)); + EchoRequest send_request; + EchoResponse send_response; + EchoResponse recv_response; + if (state.range(0) > 0) { + send_request.set_message(std::string(state.range(0), 'a')); + } + if (state.range(1) > 0) { + send_response.set_message(std::string(state.range(1), 'a')); + } + Status recv_status; + struct ServerEnv { + ServerContext ctx; + EchoRequest recv_request; + grpc::ServerAsyncResponseWriter response_writer; + ServerEnv() : response_writer(&ctx) {} + }; + uint8_t server_env_buffer[2 * sizeof(ServerEnv)]; + ServerEnv* server_env[2] = { + reinterpret_cast(server_env_buffer), + reinterpret_cast(server_env_buffer + sizeof(ServerEnv))}; + new (server_env[0]) ServerEnv; + new (server_env[1]) ServerEnv; + service.RequestEcho(&server_env[0]->ctx, &server_env[0]->recv_request, + &server_env[0]->response_writer, fixture->cq(), + fixture->cq(), tag(0)); + service.RequestEcho(&server_env[1]->ctx, &server_env[1]->recv_request, + &server_env[1]->response_writer, fixture->cq(), + fixture->cq(), tag(1)); + std::unique_ptr stub( + EchoTestService::NewStub(fixture->channel())); + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + recv_response.Clear(); + ClientContext cli_ctx; + ClientContextMutator cli_ctx_mut(&cli_ctx); + std::unique_ptr> response_reader( + stub->AsyncEcho(&cli_ctx, send_request, fixture->cq())); + void* t; + bool ok; + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + GPR_ASSERT(t == tag(0) || t == tag(1)); + intptr_t slot = reinterpret_cast(t); + ServerEnv* senv = server_env[slot]; + ServerContextMutator svr_ctx_mut(&senv->ctx); + senv->response_writer.Finish(send_response, Status::OK, tag(3)); + response_reader->Finish(&recv_response, &recv_status, tag(4)); + for (int i = (1 << 3) | (1 << 4); i != 0;) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int tagnum = (int)reinterpret_cast(t); + GPR_ASSERT(i & (1 << tagnum)); + i -= 1 << tagnum; + } + GPR_ASSERT(recv_status.ok()); + + senv->~ServerEnv(); + senv = new (senv) ServerEnv(); + service.RequestEcho(&senv->ctx, &senv->recv_request, &senv->response_writer, + fixture->cq(), fixture->cq(), tag(slot)); + } + fixture->Finish(state); + fixture.reset(); + server_env[0]->~ServerEnv(); + server_env[1]->~ServerEnv(); + state.SetBytesProcessed(state.range(0) * state.iterations() + + state.range(1) * state.iterations()); +} + +/******************************************************************************* + * CONFIGURATIONS + */ + +static void SweepSizesArgs(benchmark::internal::Benchmark* b) { + b->Args({0, 0}); + for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { + b->Args({i, 0}); + b->Args({0, i}); + b->Args({i, i}); + } +} + +BENCHMARK_TEMPLATE(BM_UnaryPingPong, TCP, NoOpMutator, NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, UDS, NoOpMutator, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, SockPair, NoOpMutator, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 0}); + +} // namespace testing +} // namespace grpc + +BENCHMARK_MAIN(); diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc index 7f81fbabcc1..ee3dec2bce0 100644 --- a/test/cpp/microbenchmarks/bm_metadata.cc +++ b/test/cpp/microbenchmarks/bm_metadata.cc @@ -36,65 +36,90 @@ #include extern "C" { +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/transport.h" } +#include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" -static class InitializeStuff { - public: - InitializeStuff() { grpc_init(); } - ~InitializeStuff() { grpc_shutdown(); } -} initialize_stuff; +auto& force_library_initialization = Library::get(); static void BM_SliceFromStatic(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { benchmark::DoNotOptimize(grpc_slice_from_static_string("abc")); } + track_counters.Finish(state); } BENCHMARK(BM_SliceFromStatic); static void BM_SliceFromCopied(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { grpc_slice_unref(grpc_slice_from_copied_string("abc")); } + track_counters.Finish(state); } BENCHMARK(BM_SliceFromCopied); +static void BM_SliceFromStreamOwnedBuffer(benchmark::State& state) { + grpc_stream_refcount r; + GRPC_STREAM_REF_INIT(&r, 1, NULL, NULL, "test"); + char buffer[64]; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + while (state.KeepRunning()) { + grpc_slice_unref_internal(&exec_ctx, grpc_slice_from_stream_owned_buffer( + &r, buffer, sizeof(buffer))); + } + grpc_exec_ctx_finish(&exec_ctx); +} +BENCHMARK(BM_SliceFromStreamOwnedBuffer); + static void BM_SliceIntern(benchmark::State& state) { + TrackCounters track_counters; gpr_slice slice = grpc_slice_from_static_string("abc"); while (state.KeepRunning()) { grpc_slice_unref(grpc_slice_intern(slice)); } + track_counters.Finish(state); } BENCHMARK(BM_SliceIntern); static void BM_SliceReIntern(benchmark::State& state) { + TrackCounters track_counters; gpr_slice slice = grpc_slice_intern(grpc_slice_from_static_string("abc")); while (state.KeepRunning()) { grpc_slice_unref(grpc_slice_intern(slice)); } grpc_slice_unref(slice); + track_counters.Finish(state); } BENCHMARK(BM_SliceReIntern); static void BM_SliceInternStaticMetadata(benchmark::State& state) { + TrackCounters track_counters; while (state.KeepRunning()) { grpc_slice_intern(GRPC_MDSTR_GZIP); } + track_counters.Finish(state); } BENCHMARK(BM_SliceInternStaticMetadata); static void BM_SliceInternEqualToStaticMetadata(benchmark::State& state) { + TrackCounters track_counters; gpr_slice slice = grpc_slice_from_static_string("gzip"); while (state.KeepRunning()) { grpc_slice_intern(slice); } + track_counters.Finish(state); } BENCHMARK(BM_SliceInternEqualToStaticMetadata); static void BM_MetadataFromNonInternedSlices(benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_from_static_string("key"); gpr_slice v = grpc_slice_from_static_string("value"); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -102,10 +127,12 @@ static void BM_MetadataFromNonInternedSlices(benchmark::State& state) { GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_create(&exec_ctx, k, v, NULL)); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromNonInternedSlices); static void BM_MetadataFromInternedSlices(benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key")); gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value")); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -115,11 +142,13 @@ static void BM_MetadataFromInternedSlices(benchmark::State& state) { grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); grpc_slice_unref(v); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromInternedSlices); static void BM_MetadataFromInternedSlicesAlreadyInIndex( benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key")); gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value")); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -131,10 +160,12 @@ static void BM_MetadataFromInternedSlicesAlreadyInIndex( grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); grpc_slice_unref(v); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromInternedSlicesAlreadyInIndex); static void BM_MetadataFromInternedKey(benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key")); gpr_slice v = grpc_slice_from_static_string("value"); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -143,11 +174,13 @@ static void BM_MetadataFromInternedKey(benchmark::State& state) { } grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromInternedKey); static void BM_MetadataFromNonInternedSlicesWithBackingStore( benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_from_static_string("key"); gpr_slice v = grpc_slice_from_static_string("value"); char backing_store[sizeof(grpc_mdelem_data)]; @@ -159,11 +192,13 @@ static void BM_MetadataFromNonInternedSlicesWithBackingStore( reinterpret_cast(backing_store))); } grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromNonInternedSlicesWithBackingStore); static void BM_MetadataFromInternedSlicesWithBackingStore( benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key")); gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value")); char backing_store[sizeof(grpc_mdelem_data)]; @@ -177,11 +212,13 @@ static void BM_MetadataFromInternedSlicesWithBackingStore( grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); grpc_slice_unref(v); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromInternedSlicesWithBackingStore); static void BM_MetadataFromInternedKeyWithBackingStore( benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key")); gpr_slice v = grpc_slice_from_static_string("value"); char backing_store[sizeof(grpc_mdelem_data)]; @@ -194,10 +231,12 @@ static void BM_MetadataFromInternedKeyWithBackingStore( } grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromInternedKeyWithBackingStore); static void BM_MetadataFromStaticMetadataStrings(benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = GRPC_MDSTR_STATUS; gpr_slice v = GRPC_MDSTR_200; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -206,11 +245,13 @@ static void BM_MetadataFromStaticMetadataStrings(benchmark::State& state) { } grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromStaticMetadataStrings); static void BM_MetadataFromStaticMetadataStringsNotIndexed( benchmark::State& state) { + TrackCounters track_counters; gpr_slice k = GRPC_MDSTR_STATUS; gpr_slice v = GRPC_MDSTR_GZIP; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -219,10 +260,12 @@ static void BM_MetadataFromStaticMetadataStringsNotIndexed( } grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(k); + track_counters.Finish(state); } BENCHMARK(BM_MetadataFromStaticMetadataStringsNotIndexed); static void BM_MetadataRefUnrefExternal(benchmark::State& state) { + TrackCounters track_counters; char backing_store[sizeof(grpc_mdelem_data)]; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem el = @@ -234,10 +277,12 @@ static void BM_MetadataRefUnrefExternal(benchmark::State& state) { } GRPC_MDELEM_UNREF(&exec_ctx, el); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_MetadataRefUnrefExternal); static void BM_MetadataRefUnrefInterned(benchmark::State& state) { + TrackCounters track_counters; char backing_store[sizeof(grpc_mdelem_data)]; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key")); @@ -251,10 +296,12 @@ static void BM_MetadataRefUnrefInterned(benchmark::State& state) { } GRPC_MDELEM_UNREF(&exec_ctx, el); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_MetadataRefUnrefInterned); static void BM_MetadataRefUnrefAllocated(benchmark::State& state) { + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem el = grpc_mdelem_create(&exec_ctx, grpc_slice_from_static_string("a"), @@ -264,10 +311,12 @@ static void BM_MetadataRefUnrefAllocated(benchmark::State& state) { } GRPC_MDELEM_UNREF(&exec_ctx, el); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_MetadataRefUnrefAllocated); static void BM_MetadataRefUnrefStatic(benchmark::State& state) { + TrackCounters track_counters; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem el = grpc_mdelem_create(&exec_ctx, GRPC_MDSTR_STATUS, GRPC_MDSTR_200, NULL); @@ -276,6 +325,7 @@ static void BM_MetadataRefUnrefStatic(benchmark::State& state) { } GRPC_MDELEM_UNREF(&exec_ctx, el); grpc_exec_ctx_finish(&exec_ctx); + track_counters.Finish(state); } BENCHMARK(BM_MetadataRefUnrefStatic); diff --git a/test/cpp/microbenchmarks/fullstack_context_mutators.h b/test/cpp/microbenchmarks/fullstack_context_mutators.h new file mode 100644 index 00000000000..676f9aa1cc6 --- /dev/null +++ b/test/cpp/microbenchmarks/fullstack_context_mutators.h @@ -0,0 +1,158 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_CPP_MICROBENCHMARKS_FULLSTACK_CONTEXT_MUTATORS_H +#define TEST_CPP_MICROBENCHMARKS_FULLSTACK_CONTEXT_MUTATORS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test/cpp/microbenchmarks/helpers.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * CONTEXT MUTATORS + */ + +static const int kPregenerateKeyCount = 100000; + +template +auto MakeVector(size_t length, F f) -> std::vector { + std::vector out; + out.reserve(length); + for (size_t i = 0; i < length; i++) { + out.push_back(f()); + } + return out; +} + +class NoOpMutator { + public: + template + NoOpMutator(ContextType* context) {} +}; + +template +class RandomBinaryMetadata { + public: + static const grpc::string& Key() { return kKey; } + + static const grpc::string& Value() { + return kValues[rand() % kValues.size()]; + } + + private: + static const grpc::string kKey; + static const std::vector kValues; + + static grpc::string GenerateOneString() { + grpc::string s; + s.reserve(length + 1); + for (int i = 0; i < length; i++) { + s += (char)rand(); + } + return s; + } +}; + +template +class RandomAsciiMetadata { + public: + static const grpc::string& Key() { return kKey; } + + static const grpc::string& Value() { + return kValues[rand() % kValues.size()]; + } + + private: + static const grpc::string kKey; + static const std::vector kValues; + + static grpc::string GenerateOneString() { + grpc::string s; + s.reserve(length + 1); + for (int i = 0; i < length; i++) { + s += (char)(rand() % 26 + 'a'); + } + return s; + } +}; + +template +class Client_AddMetadata : public NoOpMutator { + public: + Client_AddMetadata(ClientContext* context) : NoOpMutator(context) { + for (int i = 0; i < kNumKeys; i++) { + context->AddMetadata(Generator::Key(), Generator::Value()); + } + } +}; + +template +class Server_AddInitialMetadata : public NoOpMutator { + public: + Server_AddInitialMetadata(ServerContext* context) : NoOpMutator(context) { + for (int i = 0; i < kNumKeys; i++) { + context->AddInitialMetadata(Generator::Key(), Generator::Value()); + } + } +}; + +// static initialization + +template +const grpc::string RandomBinaryMetadata::kKey = "foo-bin"; + +template +const std::vector RandomBinaryMetadata::kValues = + MakeVector(kPregenerateKeyCount, GenerateOneString); + +template +const grpc::string RandomAsciiMetadata::kKey = "foo"; + +template +const std::vector RandomAsciiMetadata::kValues = + MakeVector(kPregenerateKeyCount, GenerateOneString); + +} // namespace testing +} // namespace grpc + +#endif diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h new file mode 100644 index 00000000000..dc297010599 --- /dev/null +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -0,0 +1,244 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H +#define TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/server.h" +#include "test/core/util/passthru_endpoint.h" +#include "test/core/util/port.h" +} + +#include "test/cpp/microbenchmarks/helpers.h" + +namespace grpc { +namespace testing { + +static void ApplyCommonServerBuilderConfig(ServerBuilder* b) { + b->SetMaxReceiveMessageSize(INT_MAX); + b->SetMaxSendMessageSize(INT_MAX); +} + +static void ApplyCommonChannelArguments(ChannelArguments* c) { + c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX); + c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX); +} + +class BaseFixture : public TrackCounters {}; + +class FullstackFixture : public BaseFixture { + public: + FullstackFixture(Service* service, const grpc::string& address) { + ServerBuilder b; + b.AddListeningPort(address, InsecureServerCredentials()); + cq_ = b.AddCompletionQueue(true); + b.RegisterService(service); + ApplyCommonServerBuilderConfig(&b); + server_ = b.BuildAndStart(); + ChannelArguments args; + ApplyCommonChannelArguments(&args); + channel_ = CreateCustomChannel(address, InsecureChannelCredentials(), args); + } + + virtual ~FullstackFixture() { + server_->Shutdown(); + cq_->Shutdown(); + void* tag; + bool ok; + while (cq_->Next(&tag, &ok)) { + } + } + + ServerCompletionQueue* cq() { return cq_.get(); } + std::shared_ptr channel() { return channel_; } + + private: + std::unique_ptr server_; + std::unique_ptr cq_; + std::shared_ptr channel_; +}; + +class TCP : public FullstackFixture { + public: + TCP(Service* service) : FullstackFixture(service, MakeAddress()) {} + + private: + static grpc::string MakeAddress() { + int port = grpc_pick_unused_port_or_die(); + std::stringstream addr; + addr << "localhost:" << port; + return addr.str(); + } +}; + +class UDS : public FullstackFixture { + public: + UDS(Service* service) : FullstackFixture(service, MakeAddress()) {} + + private: + static grpc::string MakeAddress() { + int port = grpc_pick_unused_port_or_die(); // just for a unique id - not a + // real port + std::stringstream addr; + addr << "unix:/tmp/bm_fullstack." << port; + return addr.str(); + } +}; + +class EndpointPairFixture : public BaseFixture { + public: + EndpointPairFixture(Service* service, grpc_endpoint_pair endpoints) + : endpoint_pair_(endpoints) { + ServerBuilder b; + cq_ = b.AddCompletionQueue(true); + b.RegisterService(service); + ApplyCommonServerBuilderConfig(&b); + server_ = b.BuildAndStart(); + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + /* add server endpoint to server_ + * */ + { + const grpc_channel_args* server_args = + grpc_server_get_channel_args(server_->c_server()); + server_transport_ = grpc_create_chttp2_transport( + &exec_ctx, server_args, endpoints.server, 0 /* is_client */); + + grpc_pollset** pollsets; + size_t num_pollsets = 0; + grpc_server_get_pollsets(server_->c_server(), &pollsets, &num_pollsets); + + for (size_t i = 0; i < num_pollsets; i++) { + grpc_endpoint_add_to_pollset(&exec_ctx, endpoints.server, pollsets[i]); + } + + grpc_server_setup_transport(&exec_ctx, server_->c_server(), + server_transport_, NULL, server_args); + grpc_chttp2_transport_start_reading(&exec_ctx, server_transport_, NULL); + } + + /* create channel */ + { + ChannelArguments args; + args.SetString(GRPC_ARG_DEFAULT_AUTHORITY, "test.authority"); + ApplyCommonChannelArguments(&args); + + grpc_channel_args c_args = args.c_channel_args(); + client_transport_ = + grpc_create_chttp2_transport(&exec_ctx, &c_args, endpoints.client, 1); + GPR_ASSERT(client_transport_); + grpc_channel* channel = + grpc_channel_create(&exec_ctx, "target", &c_args, + GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); + grpc_chttp2_transport_start_reading(&exec_ctx, client_transport_, NULL); + + channel_ = CreateChannelInternal("", channel); + } + + grpc_exec_ctx_finish(&exec_ctx); + } + + virtual ~EndpointPairFixture() { + server_->Shutdown(); + cq_->Shutdown(); + void* tag; + bool ok; + while (cq_->Next(&tag, &ok)) { + } + } + + ServerCompletionQueue* cq() { return cq_.get(); } + std::shared_ptr channel() { return channel_; } + + protected: + grpc_endpoint_pair endpoint_pair_; + grpc_transport* client_transport_; + grpc_transport* server_transport_; + + private: + std::unique_ptr server_; + std::unique_ptr cq_; + std::shared_ptr channel_; +}; + +class SockPair : public EndpointPairFixture { + public: + SockPair(Service* service) + : EndpointPairFixture(service, grpc_iomgr_create_endpoint_pair( + "test", Library::get().rq(), 8192)) {} +}; + +class InProcessCHTTP2 : public EndpointPairFixture { + public: + InProcessCHTTP2(Service* service) + : EndpointPairFixture(service, MakeEndpoints()) {} + + void AddToLabel(std::ostream& out, benchmark::State& state) { + EndpointPairFixture::AddToLabel(out, state); + out << " writes/iter:" + << ((double)stats_.num_writes / (double)state.iterations()); + } + + private: + grpc_passthru_endpoint_stats stats_; + + grpc_endpoint_pair MakeEndpoints() { + grpc_endpoint_pair p; + grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), + &stats_); + return p; + } +}; + +} // namespace testing +} // namespace grpc + +#endif diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc new file mode 100644 index 00000000000..947e81ffd83 --- /dev/null +++ b/test/cpp/microbenchmarks/helpers.cc @@ -0,0 +1,65 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/cpp/microbenchmarks/helpers.h" + +void TrackCounters::Finish(benchmark::State &state) { + std::ostringstream out; + AddToLabel(out, state); + auto label = out.str(); + if (label.length() && label[0] == ' ') { + label = label.substr(1); + } + state.SetLabel(label); +} + +void TrackCounters::AddToLabel(std::ostream &out, benchmark::State &state) { +#ifdef GPR_LOW_LEVEL_COUNTERS + out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) - + mu_locks_at_start_) / + (double)state.iterations()) + << " atm_cas/iter:" + << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_cas) - + atm_cas_at_start_) / + (double)state.iterations()) + << " atm_add/iter:" + << ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) - + atm_add_at_start_) / + (double)state.iterations()); +#endif + grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot(); + out << " allocs/iter:" + << ((double)(counters_at_end.total_allocs_absolute - + counters_at_start_.total_allocs_absolute) / + (double)state.iterations()); +} diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h new file mode 100644 index 00000000000..42a8fbaf0bf --- /dev/null +++ b/test/cpp/microbenchmarks/helpers.h @@ -0,0 +1,91 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_CPP_MICROBENCHMARKS_COUNTERS_H +#define TEST_CPP_MICROBENCHMARKS_COUNTERS_H + +#include + +extern "C" { +#include +#include "test/core/util/memory_counters.h" +} + +#include +#include "third_party/benchmark/include/benchmark/benchmark.h" + +class Library { + public: + static Library& get() { + static Library lib; + return lib; + } + + grpc_resource_quota* rq() { return rq_; } + + private: + Library() { + grpc_memory_counters_init(); + init_lib_.init(); + rq_ = grpc_resource_quota_create("bm"); + } + + ~Library() { init_lib_.shutdown(); } + + grpc::internal::GrpcLibrary init_lib_; + grpc_resource_quota* rq_; +}; + +#ifdef GPR_LOW_LEVEL_COUNTERS +extern "C" gpr_atm gpr_mu_locks; +extern "C" gpr_atm gpr_counter_atm_cas; +extern "C" gpr_atm gpr_counter_atm_add; +#endif + +class TrackCounters { + public: + virtual void Finish(benchmark::State& state); + virtual void AddToLabel(std::ostream& out, benchmark::State& state); + + private: +#ifdef GPR_LOW_LEVEL_COUNTERS + const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks); + const size_t atm_cas_at_start_ = + gpr_atm_no_barrier_load(&gpr_counter_atm_cas); + const size_t atm_add_at_start_ = + gpr_atm_no_barrier_load(&gpr_counter_atm_add); +#endif + grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot(); +}; + +#endif diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc new file mode 100644 index 00000000000..1d9eda17b40 --- /dev/null +++ b/test/cpp/server/server_builder_test.cc @@ -0,0 +1,96 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" + +namespace grpc { +namespace { + +testing::EchoTestService::Service g_service; + +grpc::string MakePort() { + std::ostringstream s; + int p = grpc_pick_unused_port_or_die(); + s << "localhost:" << p; + return s.str(); +} + +grpc::string g_port = MakePort(); + +TEST(ServerBuilderTest, NoOp) { ServerBuilder b; } + +TEST(ServerBuilderTest, CreateServerNoPorts) { + ServerBuilder().RegisterService(&g_service).BuildAndStart()->Shutdown(); +} + +TEST(ServerBuilderTest, CreateServerOnePort) { + ServerBuilder() + .RegisterService(&g_service) + .AddListeningPort(g_port, InsecureServerCredentials()) + .BuildAndStart() + ->Shutdown(); +} + +TEST(ServerBuilderTest, CreateServerRepeatedPort) { + ServerBuilder() + .RegisterService(&g_service) + .AddListeningPort(g_port, InsecureServerCredentials()) + .AddListeningPort(g_port, InsecureServerCredentials()) + .BuildAndStart() + ->Shutdown(); +} + +TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { + EXPECT_EQ(ServerBuilder() + .RegisterService(&g_service) + .AddListeningPort(g_port, InsecureServerCredentials()) + .AddListeningPort(g_port, InsecureServerCredentials()) + .AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0) + .BuildAndStart(), + nullptr); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/third_party/protobuf b/third_party/protobuf index a428e420727..593e917c176 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit a428e42072765993ff674fda72863c9f1aa2d268 +Subproject commit 593e917c176b5bc5aafa57bf9f6030d749d91cd5 diff --git a/tools/distrib/python/bazel_deps.sh b/tools/distrib/python/bazel_deps.sh index de3ee079708..f6d42d29eb6 100755 --- a/tools/distrib/python/bazel_deps.sh +++ b/tools/distrib/python/bazel_deps.sh @@ -33,14 +33,14 @@ cd $(dirname $0)/../../../ # First check if bazel is installed on the machine. If it is, then we don't need # to invoke the docker bazel. -if [ "bazel version" ] +if [ -x "$(command -v bazel)" ] then cd third_party/protobuf bazel query 'deps('$1')' else - docker build -t bazel `realpath ./tools/dockerfile/bazel/` - docker run -v "`realpath .`:/src/grpc/" \ - -w /src/grpc/third_party/protobuf \ - bazel \ + docker build -t bazel_local_img tools/dockerfile/test/sanity + docker run -v "$(realpath .):/src/grpc/:ro" \ + -w /src/grpc/third_party/protobuf \ + bazel_local_img \ bazel query 'deps('$1')' fi diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc b/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc new file mode 100644 index 00000000000..682837a27f0 --- /dev/null +++ b/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc @@ -0,0 +1,343 @@ +// Copyright 2017, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// HACK: Embed the generated well_known_types_js.cc to make +// grpc-tools python package compilation easy. +#include +struct FileToc well_known_types_js[] = { +{"any.js", + "// Protocol Buffers - Google's data interchange format\n" + "// Copyright 2008 Google Inc. All rights reserved.\n" + "// https://developers.google.com/protocol-buffers/\n" + "//\n" + "// Redistribution and use in source and binary forms, with or without\n" + "// modification, are permitted provided that the following conditions are\n" + "// met:\n" + "//\n" + "// * Redistributions of source code must retain the above copyright\n" + "// notice, this list of conditions and the following disclaimer.\n" + "// * Redistributions in binary form must reproduce the above\n" + "// copyright notice, this list of conditions and the following disclaimer\n" + "// in the documentation and/or other materials provided with the\n" + "// distribution.\n" + "// * Neither the name of Google Inc. nor the names of its\n" + "// contributors may be used to endorse or promote products derived from\n" + "// this software without specific prior written permission.\n" + "//\n" + "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" + "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" + "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" + "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" + "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" + "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" + "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" + "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" + "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" + "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "\n" + "/* This code will be inserted into generated code for\n" + " * google/protobuf/any.proto. */\n" + "\n" + "/**\n" + " * Returns the type name contained in this instance, if any.\n" + " * @return {string|undefined}\n" + " */\n" + "proto.google.protobuf.Any.prototype.getTypeName = function() {\n" + " return this.getTypeUrl().split('/').pop();\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Packs the given message instance into this Any.\n" + " * @param {!Uint8Array} serialized The serialized data to pack.\n" + " * @param {string} name The type name of this message object.\n" + " * @param {string=} opt_typeUrlPrefix the type URL prefix.\n" + " */\n" + "proto.google.protobuf.Any.prototype.pack = function(serialized, name,\n" + " opt_typeUrlPrefix) {\n" + " if (!opt_typeUrlPrefix) {\n" + " opt_typeUrlPrefix = 'type.googleapis.com/';\n" + " }\n" + "\n" + " if (opt_typeUrlPrefix.substr(-1) != '/') {\n" + " this.setTypeUrl(opt_typeUrlPrefix + '/' + name);\n" + " } else {\n" + " this.setTypeUrl(opt_typeUrlPrefix + name);\n" + " }\n" + "\n" + " this.setValue(serialized);\n" + "};\n" + "\n" + "\n" + "/**\n" + " * @template T\n" + " * Unpacks this Any into the given message object.\n" + " * @param {function(Uint8Array):T} deserialize Function that will deserialize\n" + " * the binary data properly.\n" + " * @param {string} name The expected type name of this message object.\n" + " * @return {?T} If the name matched the expected name, returns the deserialized\n" + " * object, otherwise returns undefined.\n" + " */\n" + "proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) {\n" + " if (this.getTypeName() == name) {\n" + " return deserialize(this.getValue_asU8());\n" + " } else {\n" + " return null;\n" + " }\n" + "};\n" +}, +{"struct.js", + "// Protocol Buffers - Google's data interchange format\n" + "// Copyright 2008 Google Inc. All rights reserved.\n" + "// https://developers.google.com/protocol-buffers/\n" + "//\n" + "// Redistribution and use in source and binary forms, with or without\n" + "// modification, are permitted provided that the following conditions are\n" + "// met:\n" + "//\n" + "// * Redistributions of source code must retain the above copyright\n" + "// notice, this list of conditions and the following disclaimer.\n" + "// * Redistributions in binary form must reproduce the above\n" + "// copyright notice, this list of conditions and the following disclaimer\n" + "// in the documentation and/or other materials provided with the\n" + "// distribution.\n" + "// * Neither the name of Google Inc. nor the names of its\n" + "// contributors may be used to endorse or promote products derived from\n" + "// this software without specific prior written permission.\n" + "//\n" + "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" + "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" + "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" + "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" + "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" + "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" + "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" + "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" + "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" + "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "\n" + "/* This code will be inserted into generated code for\n" + " * google/protobuf/struct.proto. */\n" + "\n" + "/**\n" + " * Typedef representing plain JavaScript values that can go into a\n" + " * Struct.\n" + " * @typedef {null|number|string|boolean|Array|Object}\n" + " */\n" + "proto.google.protobuf.JavaScriptValue;\n" + "\n" + "\n" + "/**\n" + " * Converts this Value object to a plain JavaScript value.\n" + " * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript\n" + " * value representing this Struct.\n" + " */\n" + "proto.google.protobuf.Value.prototype.toJavaScript = function() {\n" + " var kindCase = proto.google.protobuf.Value.KindCase;\n" + " switch (this.getKindCase()) {\n" + " case kindCase.NULL_VALUE:\n" + " return null;\n" + " case kindCase.NUMBER_VALUE:\n" + " return this.getNumberValue();\n" + " case kindCase.STRING_VALUE:\n" + " return this.getStringValue();\n" + " case kindCase.BOOL_VALUE:\n" + " return this.getBoolValue();\n" + " case kindCase.STRUCT_VALUE:\n" + " return this.getStructValue().toJavaScript();\n" + " case kindCase.LIST_VALUE:\n" + " return this.getListValue().toJavaScript();\n" + " default:\n" + " throw new Error('Unexpected struct type');\n" + " }\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Converts this JavaScript value to a new Value proto.\n" + " * @param {!proto.google.protobuf.JavaScriptValue} value The value to\n" + " * convert.\n" + " * @return {!proto.google.protobuf.Value} The newly constructed value.\n" + " */\n" + "proto.google.protobuf.Value.fromJavaScript = function(value) {\n" + " var ret = new proto.google.protobuf.Value();\n" + " switch (goog.typeOf(value)) {\n" + " case 'string':\n" + " ret.setStringValue(/** @type {string} */ (value));\n" + " break;\n" + " case 'number':\n" + " ret.setNumberValue(/** @type {number} */ (value));\n" + " break;\n" + " case 'boolean':\n" + " ret.setBoolValue(/** @type {boolean} */ (value));\n" + " break;\n" + " case 'null':\n" + " ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);\n" + " break;\n" + " case 'array':\n" + " ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(\n" + " /** @type{!Array} */ (value)));\n" + " break;\n" + " case 'object':\n" + " ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(\n" + " /** @type{!Object} */ (value)));\n" + " break;\n" + " default:\n" + " throw new Error('Unexpected struct type.');\n" + " }\n" + "\n" + " return ret;\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Converts this ListValue object to a plain JavaScript array.\n" + " * @return {!Array} a plain JavaScript array representing this List.\n" + " */\n" + "proto.google.protobuf.ListValue.prototype.toJavaScript = function() {\n" + " var ret = [];\n" + " var values = this.getValuesList();\n" + "\n" + " for (var i = 0; i < values.length; i++) {\n" + " ret[i] = values[i].toJavaScript();\n" + " }\n" + "\n" + " return ret;\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Constructs a ListValue protobuf from this plain JavaScript array.\n" + " * @param {!Array} array a plain JavaScript array\n" + " * @return {proto.google.protobuf.ListValue} a new ListValue object\n" + " */\n" + "proto.google.protobuf.ListValue.fromJavaScript = function(array) {\n" + " var ret = new proto.google.protobuf.ListValue();\n" + "\n" + " for (var i = 0; i < array.length; i++) {\n" + " ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));\n" + " }\n" + "\n" + " return ret;\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Converts this Struct object to a plain JavaScript object.\n" + " * @return {!Object} a plain\n" + " * JavaScript object representing this Struct.\n" + " */\n" + "proto.google.protobuf.Struct.prototype.toJavaScript = function() {\n" + " var ret = {};\n" + "\n" + " this.getFieldsMap().forEach(function(value, key) {\n" + " ret[key] = value.toJavaScript();\n" + " });\n" + "\n" + " return ret;\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Constructs a Struct protobuf from this plain JavaScript object.\n" + " * @param {!Object} obj a plain JavaScript object\n" + " * @return {proto.google.protobuf.Struct} a new Struct object\n" + " */\n" + "proto.google.protobuf.Struct.fromJavaScript = function(obj) {\n" + " var ret = new proto.google.protobuf.Struct();\n" + " var map = ret.getFieldsMap();\n" + "\n" + " for (var property in obj) {\n" + " var val = obj[property];\n" + " map.set(property, proto.google.protobuf.Value.fromJavaScript(val));\n" + " }\n" + "\n" + " return ret;\n" + "};\n" +}, +{"timestamp.js", + "// Protocol Buffers - Google's data interchange format\n" + "// Copyright 2008 Google Inc. All rights reserved.\n" + "// https://developers.google.com/protocol-buffers/\n" + "//\n" + "// Redistribution and use in source and binary forms, with or without\n" + "// modification, are permitted provided that the following conditions are\n" + "// met:\n" + "//\n" + "// * Redistributions of source code must retain the above copyright\n" + "// notice, this list of conditions and the following disclaimer.\n" + "// * Redistributions in binary form must reproduce the above\n" + "// copyright notice, this list of conditions and the following disclaimer\n" + "// in the documentation and/or other materials provided with the\n" + "// distribution.\n" + "// * Neither the name of Google Inc. nor the names of its\n" + "// contributors may be used to endorse or promote products derived from\n" + "// this software without specific prior written permission.\n" + "//\n" + "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" + "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" + "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" + "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" + "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" + "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" + "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" + "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" + "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" + "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "\n" + "/* This code will be inserted into generated code for\n" + " * google/protobuf/timestamp.proto. */\n" + "\n" + "/**\n" + " * Returns a JavaScript 'Date' object corresponding to this Timestamp.\n" + " * @return {!Date}\n" + " */\n" + "proto.google.protobuf.Timestamp.prototype.toDate = function() {\n" + " var seconds = this.getSeconds();\n" + " var nanos = this.getNanos();\n" + "\n" + " return new Date((seconds * 1000) + (nanos / 1000000));\n" + "};\n" + "\n" + "\n" + "/**\n" + " * Sets the value of this Timestamp object to be the given Date.\n" + " * @param {!Date} value The value to set.\n" + " */\n" + "proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {\n" + " var millis = value.getTime();\n" + " this.setSeconds(Math.floor(value.getTime() / 1000));\n" + " this.setNanos(value.getMilliseconds() * 1000000);\n" + "};\n" +}, + {NULL, NULL} // Terminate the list. +}; diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index 569328e57ea..c2aa6198b3d 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -29,7 +29,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # AUTO-GENERATED BY make_grpcio_tools.py! -CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc'] +CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc', 'google/protobuf/compiler/js/embed.cc'] PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto'] CC_INCLUDE='third_party/protobuf/src' diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 502d7ef27b8..ed27f1f8350 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -157,11 +157,28 @@ def extension_modules(): plugin_sources = [os.path.join('grpc_tools', '_protoc_compiler.pyx')] else: plugin_sources = [os.path.join('grpc_tools', '_protoc_compiler.cpp')] + plugin_sources += [ os.path.join('grpc_tools', 'main.cc'), - os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [ - os.path.join(CC_INCLUDE, cc_file) - for cc_file in CC_FILES] + os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + + #HACK: Substitute the embed.cc, which is a JS to C++ + # preprocessor with the generated code. + # The generated code should not be material + # to the parts of protoc we use (it affects + # the JavaScript code generator, supposedly), + # but we need to be cautious about it. + cc_files_clone = list(CC_FILES) + embed_cc_file = os.path.normpath('google/protobuf/compiler/js/embed.cc') + well_known_types_file = os.path.normpath( + 'google/protobuf/compiler/js/well_known_types_embed.cc') + if embed_cc_file in cc_files_clone: + cc_files_clone.remove(embed_cc_file) + if well_known_types_file in cc_files_clone: + cc_files_clone.remove(well_known_types_file) + plugin_sources += [os.path.join('grpc_tools', 'protobuf_generated_well_known_types_embed.cc')] + plugin_sources += [os.path.join(CC_INCLUDE, cc_file) for cc_file in cc_files_clone] + plugin_ext = extension.Extension( name='grpc_tools._protoc_compiler', sources=plugin_sources, @@ -190,7 +207,7 @@ setuptools.setup( ext_modules=extension_modules(), packages=setuptools.find_packages('.'), install_requires=[ - 'protobuf>=3.0.0', + 'protobuf>=3.2.0', 'grpcio>={version}'.format(version=grpc_version.VERSION), ], package_data=package_data(), diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 669e3557b89..34799447171 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 ################## diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index 860b8f4fb94..75d156f6d85 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 ################## diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile index 087cc4e2bb4..14a2468abc7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================ # C# dependencies diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile index efe6e39118b..c26c9a2826e 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================ # C# dependencies @@ -99,8 +99,12 @@ RUN nuget update -self # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 -RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.0-preview2-003121 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.1 +RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 +RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile index aa77d5f1272..2d10e3fdfef 100644 --- a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh index 7a7ca0d3d1c..0a61334103b 100755 --- a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh @@ -47,3 +47,6 @@ make install-certs # build C++ interop client & server make interop_client interop_server + +# build C++ http2 client +make http2_client diff --git a/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile index 05e963d1e67..d3bf071c72e 100644 --- a/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile @@ -45,7 +45,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile index 3a5e15d21bd..66d9b4f6403 100644 --- a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile @@ -45,7 +45,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 RUN pip install twisted h2 diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile index b5fe54f9918..2023467d593 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile @@ -60,7 +60,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Trigger download of as many Gradle artifacts as possible. diff --git a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile index d9a75018295..9945260ea4a 100644 --- a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================== # Node dependencies diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile index 10a88916ada..94c17078d34 100644 --- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile index dae64e5c8cb..679c8ff47a6 100644 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================== # Ruby dependencies diff --git a/tools/dockerfile/push_testing_images.sh b/tools/dockerfile/push_testing_images.sh index 9dceb29a877..973e045ffe4 100755 --- a/tools/dockerfile/push_testing_images.sh +++ b/tools/dockerfile/push_testing_images.sh @@ -44,7 +44,7 @@ cd - DOCKERHUB_ORGANIZATION=grpctesting -for DOCKERFILE_DIR in tools/dockerfile/test/fuzzer tools/dockerfile/test/sanity +for DOCKERFILE_DIR in tools/dockerfile/test/* do # Generate image name based on Dockerfile checksum. That works well as long # as can count on dockerfiles being written in a way that changing the logical diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile index 328825392b7..cd1e9343417 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile index e082da648b3..d0f66d99556 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_cxx/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile index 1e2b7d8c671..bbf7de7f91d 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile @@ -47,7 +47,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Using login shell removes Go from path, so we add it. RUN ln -s /usr/local/go/bin/go /usr/local/bin diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile index 0c17ff595ef..229ea469c42 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile index 0594f69a5b8..5fd0bc0eb21 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_node/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================== # Node dependencies diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile index 0fe9c151e53..b5198b46529 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================== # Ruby dependencies diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile index 20d2d3f57be..8e1de51f331 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_python/Dockerfile @@ -93,7 +93,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 RUN pip install coverage diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile index f459153fe54..9d291aac583 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_ruby/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile index efe6e39118b..c26c9a2826e 100644 --- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================ # C# dependencies @@ -99,8 +99,12 @@ RUN nuget update -self # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext -RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 -RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.0-preview2-003121 +RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 +RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet +# dotnet-dev-1.0.1 +RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 +RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile index 087cc4e2bb4..14a2468abc7 100644 --- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================ # C# dependencies diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile index e968a0f589b..4bb97c7aa9e 100644 --- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile index f9854802546..c4b710b5dfb 100644 --- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile index 2b3f4af3e6d..bd742dff341 100644 --- a/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile index 2d282276d31..bc46b3055a6 100644 --- a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile index f22fcacc139..f7d7f542c11 100644 --- a/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile index bd04f07cea5..b398b70b64f 100644 --- a/tools/dockerfile/test/fuzzer/Dockerfile +++ b/tools/dockerfile/test/fuzzer/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # C++ dependencies diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile index 2540b52ec8f..5d0c1686f18 100644 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile @@ -133,7 +133,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile index 7f93933ecac..4595aa6bea1 100644 --- a/tools/dockerfile/test/node_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile @@ -87,7 +87,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================== # Node dependencies diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 221338956ef..0e2c103afd1 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -88,7 +88,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index 17ea36b76c4..c6f3dde39a5 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================= # PHP dependencies diff --git a/tools/dockerfile/test/python_jessie_x64/Dockerfile b/tools/dockerfile/test/python_jessie_x64/Dockerfile index 10a88916ada..94c17078d34 100644 --- a/tools/dockerfile/test/python_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/python_jessie_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_pyenv_x64/Dockerfile index ecd785a86d3..435a9fdc978 100644 --- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile +++ b/tools/dockerfile/test/python_pyenv_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 # Install dependencies for pyenv RUN apt-get update && apt-get install -y \ @@ -92,6 +92,9 @@ RUN apt-get update && apt-get install -y \ # Install Pyenv and dev Python versions 3.5 and 3.6 RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash +ENV PATH /root/.pyenv/bin:$PATH +RUN eval "$(pyenv init -)" +RUN eval "$(pyenv virtualenv-init -)" RUN pyenv update RUN pyenv install 3.5-dev RUN pyenv install 3.6-dev diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile index dae64e5c8cb..679c8ff47a6 100644 --- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #================== # Ruby dependencies diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index 811384fda14..0da2a1914ac 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get install -y \ # Install Python packages from PyPI RUN pip install pip --upgrade RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0 #======================== # Sanity test dependencies diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 551ba46b3b8..a181defbfd0 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -779,12 +779,14 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/server_side_auth.md \ doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ @@ -801,6 +803,7 @@ include/grpc++/generic/generic_stub.h \ include/grpc++/grpc++.h \ include/grpc++/health_check_service_interface.h \ include/grpc++/impl/call.h \ +include/grpc++/impl/channel_argument_option.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/codegen/async_stream.h \ include/grpc++/impl/codegen/async_unary_call.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 0d7ddfc6d67..7595081f4fb 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -779,12 +779,14 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/server_side_auth.md \ doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ @@ -801,6 +803,7 @@ include/grpc++/generic/generic_stub.h \ include/grpc++/grpc++.h \ include/grpc++/health_check_service_interface.h \ include/grpc++/impl/call.h \ +include/grpc++/impl/channel_argument_option.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/codegen/async_stream.h \ include/grpc++/impl/codegen/async_unary_call.h \ @@ -912,6 +915,7 @@ src/cpp/common/secure_channel_arguments.cc \ src/cpp/common/secure_create_auth_context.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ +src/cpp/server/channel_argument_option.cc \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.h \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 896ee0213b3..478bdb2d042 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -778,12 +778,14 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/server_side_auth.md \ doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 04fd7bee222..a7d6aaeb9ef 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -778,12 +778,14 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/server_side_auth.md \ doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index ab29e015e04..3380f3de3e5 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -142,7 +142,7 @@ gem install bundler # Significant performance improvements with grpc-go have been observed after # upgrading from go 1.5 to a later version, so a later go version is preferred. # Following go install instructions from https://golang.org/doc/install -GO_VERSION=1.7.1 +GO_VERSION=1.8 OS=linux ARCH=amd64 curl -O https://storage.googleapis.com/golang/go${GO_VERSION}.${OS}-${ARCH}.tar.gz diff --git a/tools/internal_ci/linux/grpc_master.cfg b/tools/internal_ci/linux/grpc_master.cfg index 7536a91a679..6c94c3b4d8f 100644 --- a/tools/internal_ci/linux/grpc_master.cfg +++ b/tools/internal_ci/linux/grpc_master.cfg @@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/linux/grpc_master.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/*sponge_log.xml" } } diff --git a/tools/internal_ci/linux/grpc_master.sh b/tools/internal_ci/linux/grpc_master.sh index d01d6375e9a..9ecf1239594 100755 --- a/tools/internal_ci/linux/grpc_master.sh +++ b/tools/internal_ci/linux/grpc_master.sh @@ -45,6 +45,8 @@ ulimit -n 2000 git submodule update --init +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting tools/run_tests/run_tests.py -l c -t -x sponge_log.xml || FAILED="true" # kill port_server.py to prevent the build from hanging diff --git a/tools/internal_ci/linux/grpc_master_sanitizers.cfg b/tools/internal_ci/linux/grpc_master_sanitizers.cfg new file mode 100644 index 00000000000..a2a9407128b --- /dev/null +++ b/tools/internal_ci/linux/grpc_master_sanitizers.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_master_sanitizers.sh" +timeout_mins: 1440 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/dockerfile/bazel/Dockerfile b/tools/internal_ci/linux/grpc_master_sanitizers.sh similarity index 72% rename from tools/dockerfile/bazel/Dockerfile rename to tools/internal_ci/linux/grpc_master_sanitizers.sh index 2a80a4d4d53..2cd0efe1588 100644 --- a/tools/dockerfile/bazel/Dockerfile +++ b/tools/internal_ci/linux/grpc_master_sanitizers.sh @@ -1,4 +1,5 @@ -# Copyright 2015, Google Inc. +#!/bin/bash +# Copyright 2017, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,26 +28,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -FROM ubuntu:wily -RUN apt-get update -RUN apt-get -y install software-properties-common python-software-properties -RUN add-apt-repository ppa:webupd8team/java -RUN apt-get update -RUN apt-get -y install \ - vim \ - wget \ - openjdk-8-jdk \ - pkg-config \ - zip \ - g++ \ - zlib1g-dev \ - unzip \ - git +set -ex -RUN git clone https://github.com/bazelbuild/bazel.git /bazel -RUN cd /bazel && ./compile.sh +# change to grpc repo root +cd $(dirname $0)/../../.. -RUN ln -s /bazel/output/bazel /bin/ +git submodule update --init -# ensure the installation has been extracted -RUN bazel +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting +tools/run_tests/run_tests_matrix.sh -f sanitizers linux diff --git a/tools/internal_ci/linux/grpc_portability.cfg b/tools/internal_ci/linux/grpc_portability.cfg new file mode 100644 index 00000000000..0c25661d624 --- /dev/null +++ b/tools/internal_ci/linux/grpc_portability.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_portability.sh" +timeout_mins: 360 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/internal_ci/linux/grpc_portability.sh b/tools/internal_ci/linux/grpc_portability.sh new file mode 100644 index 00000000000..c7ac3bbcbee --- /dev/null +++ b/tools/internal_ci/linux/grpc_portability.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + +git submodule update --init + +# download docker images from dockerhub +export DOCKERHUB_ORGANIZATION=grpctesting +tools/run_tests/run_tests_matrix.sh -f portability linux diff --git a/tools/internal_ci/linux/grpc_portability_build_only.cfg b/tools/internal_ci/linux/grpc_portability_build_only.cfg index ce5be5abe97..4d3dda40822 100644 --- a/tools/internal_ci/linux/grpc_portability_build_only.cfg +++ b/tools/internal_ci/linux/grpc_portability_build_only.cfg @@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/linux/grpc_portability_build_only.sh" timeout_mins: 180 action { define_artifacts { - regex: "**report**.xml" + regex: "**/*sponge_log.xml" } } diff --git a/tools/internal_ci/linux/grpc_portability_build_only.sh b/tools/internal_ci/linux/grpc_portability_build_only.sh index ebdc0e82d76..edd6f916872 100644 --- a/tools/internal_ci/linux/grpc_portability_build_only.sh +++ b/tools/internal_ci/linux/grpc_portability_build_only.sh @@ -37,5 +37,4 @@ git submodule update --init # download docker images from dockerhub export DOCKERHUB_ORGANIZATION=grpctesting - -tools/jenkins/run_jenkins_matrix.sh -f portability linux --build_only +tools/run_tests/run_tests_matrix.sh -f portability linux --build_only diff --git a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg index 511f2d6b35b..1abf6ac600b 100644 --- a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg +++ b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg @@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/linux/grpc_sanity.sh" timeout_mins: 30 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/*sponge_log.xml" } } diff --git a/tools/internal_ci/windows/grpc_master.bat b/tools/internal_ci/windows/grpc_master.bat index 4041c503139..8943390a8de 100644 --- a/tools/internal_ci/windows/grpc_master.bat +++ b/tools/internal_ci/windows/grpc_master.bat @@ -27,18 +27,17 @@ @rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -setlocal +@rem make sure msys binaries are preferred over cygwin binaries +@rem set path to python 2.7 +set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% @rem enter repo root cd /d %~dp0\..\..\.. git submodule update --init -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x c_windows_dbg_sponge_log.xml --report_suite_name c_windows_dbg -l c -c dbg -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x c_windows_opt_sponge_log.xml --report_suite_name c_windows_opt -l c -c opt -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x csharp_windows_dbg_sponge_log.xml --report_suite_name csharp_windows_dbg -l csharp -c dbg -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x csharp_windows_opt_sponge_log.xml --report_suite_name csharp_windows_opt -l csharp -c opt -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x node_windows_dbg_sponge_log.xml --report_suite_name node_windows_dbg -l node -c dbg -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x node_windows_opt_sponge_log.xml --report_suite_name node_windows_opt -l node -c opt -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x python_windows_dbg_sponge_log.xml --report_suite_name python_windows_dbg -l python -c dbg -sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x python_windows_opt_sponge_log.xml --report_suite_name python_windows_opt -l python -c opt +python tools/run_tests/run_tests_matrix.py -f basictests windows -j 1 --inner_jobs 8 || goto :error +goto :EOF + +:error +exit /b %errorlevel% diff --git a/tools/internal_ci/windows/grpc_master.cfg b/tools/internal_ci/windows/grpc_master.cfg index f90af113085..21a9d6a985d 100644 --- a/tools/internal_ci/windows/grpc_master.cfg +++ b/tools/internal_ci/windows/grpc_master.cfg @@ -34,6 +34,6 @@ build_file: "grpc/tools/internal_ci/windows/grpc_master.bat" timeout_mins: 360 action { define_artifacts { - regex: "**sponge_log.xml" + regex: "**/*sponge_log.xml" } } diff --git a/tools/internal_ci/windows/grpc_portability_master.bat b/tools/internal_ci/windows/grpc_portability_master.bat new file mode 100644 index 00000000000..b98c70146c4 --- /dev/null +++ b/tools/internal_ci/windows/grpc_portability_master.bat @@ -0,0 +1,43 @@ +@rem Copyright 2017, Google Inc. +@rem All rights reserved. +@rem +@rem Redistribution and use in source and binary forms, with or without +@rem modification, are permitted provided that the following conditions are +@rem met: +@rem +@rem * Redistributions of source code must retain the above copyright +@rem notice, this list of conditions and the following disclaimer. +@rem * Redistributions in binary form must reproduce the above +@rem copyright notice, this list of conditions and the following disclaimer +@rem in the documentation and/or other materials provided with the +@rem distribution. +@rem * Neither the name of Google Inc. nor the names of its +@rem contributors may be used to endorse or promote products derived from +@rem this software without specific prior written permission. +@rem +@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@rem make sure msys binaries are preferred over cygwin binaries +@rem set path to python 2.7 +set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% + +@rem enter repo root +cd /d %~dp0\..\..\.. + +git submodule update --init + +python tools/run_tests/run_tests_matrix.py -f portability windows -j 1 --inner_jobs 8 || goto :error +goto :EOF + +:error +exit /b %errorlevel% diff --git a/tools/internal_ci/windows/grpc_portability_master.cfg b/tools/internal_ci/windows/grpc_portability_master.cfg new file mode 100644 index 00000000000..10d8e985910 --- /dev/null +++ b/tools/internal_ci/windows/grpc_portability_master.cfg @@ -0,0 +1,39 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_portability_master.bat" +timeout_mins: 360 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} diff --git a/tools/jenkins/run_full_performance_released.sh b/tools/jenkins/run_full_performance_released.sh new file mode 100755 index 00000000000..ae2289e32c9 --- /dev/null +++ b/tools/jenkins/run_full_performance_released.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# A frozen version of run_full_performance.sh that runs full performance test +# suite for the latest released stable version of gRPC. +set -ex + +# Enter the gRPC repo root +cd $(dirname $0)/../.. + +# run 8core client vs 8core server +tools/run_tests/run_performance_tests.py \ + -l c++ csharp node ruby java python go node_express \ + --netperf \ + --category scalable \ + --bq_result_table performance_released.performance_experiment \ + --remote_worker_host grpc-performance-server-8core grpc-performance-client-8core grpc-performance-client2-8core \ + --xml_report report_8core.xml \ + || EXIT_CODE=1 + +# prevent pushing leftover build files to remote hosts in the next step. +git clean -fdxq --exclude='report*.xml' + +# scalability with 32cores (and upload to a different BQ table) +tools/run_tests/run_performance_tests.py \ + -l c++ java csharp go \ + --netperf \ + --category scalable \ + --bq_result_table performance_released.performance_experiment_32core \ + --remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \ + --xml_report report_32core.xml \ + || EXIT_CODE=1 + +# prevent pushing leftover build files to remote hosts in the next step. +git clean -fdxq --exclude='report*.xml' + +# selected scenarios on Windows +tools/run_tests/run_performance_tests.py \ + -l csharp \ + --category scalable \ + --bq_result_table performance_released.performance_experiment_windows \ + --remote_worker_host grpc-performance-windows1 grpc-performance-windows2 \ + --xml_report report_windows.xml \ + || EXIT_CODE=1 + +exit $EXIT_CODE diff --git a/tools/profiling/microbenchmarks/bm2bq.py b/tools/profiling/microbenchmarks/bm2bq.py index 280f217e690..ae59332f1b3 100755 --- a/tools/profiling/microbenchmarks/bm2bq.py +++ b/tools/profiling/microbenchmarks/bm2bq.py @@ -36,7 +36,7 @@ import sys import json import csv -import os +import bm_json columns = [ ('jenkins_build', 'integer'), @@ -80,139 +80,16 @@ if sys.argv[1] == '--schema': with open(sys.argv[1]) as f: js = json.loads(f.read()) -writer = csv.DictWriter(sys.stdout, [c for c,t in columns]) - -bm_specs = { - 'BM_UnaryPingPong': { - 'tpl': ['fixture', 'client_mutator', 'server_mutator'], - 'dyn': ['request_size', 'response_size'], - }, - 'BM_PumpStreamClientToServer': { - 'tpl': ['fixture'], - 'dyn': ['request_size'], - }, - 'BM_PumpStreamServerToClient': { - 'tpl': ['fixture'], - 'dyn': ['request_size'], - }, - 'BM_StreamingPingPong': { - 'tpl': ['fixture', 'client_mutator', 'server_mutator'], - 'dyn': ['request_size', 'request_count'], - }, - 'BM_StreamingPingPongMsgs': { - 'tpl': ['fixture', 'client_mutator', 'server_mutator'], - 'dyn': ['request_size'], - }, - 'BM_PumpStreamServerToClient_Trickle': { - 'tpl': [], - 'dyn': ['request_size', 'bandwidth_kilobits'], - }, - 'BM_ErrorStringOnNewError': { - 'tpl': ['fixture'], - 'dyn': [], - }, - 'BM_ErrorStringRepeatedly': { - 'tpl': ['fixture'], - 'dyn': [], - }, - 'BM_ErrorGetStatus': { - 'tpl': ['fixture'], - 'dyn': [], - }, - 'BM_ErrorGetStatusCode': { - 'tpl': ['fixture'], - 'dyn': [], - }, - 'BM_ErrorHttpError': { - 'tpl': ['fixture'], - 'dyn': [], - }, - 'BM_HasClearGrpcStatus': { - 'tpl': ['fixture'], - 'dyn': [], - }, - 'BM_IsolatedFilter' : { - 'tpl': ['fixture', 'client_mutator'], - 'dyn': [], - }, - 'BM_HpackEncoderEncodeHeader' : { - 'tpl': ['fixture'], - 'dyn': ['end_of_stream', 'request_size'], - }, - 'BM_HpackParserParseHeader' : { - 'tpl': ['fixture'], - 'dyn': [], - }, -} +if len(sys.argv) > 2: + with open(sys.argv[2]) as f: + js2 = json.loads(f.read()) +else: + js2 = None -def numericalize(s): - if not s: return '' - if s[-1] == 'k': - return int(s[:-1]) * 1024 - if s[-1] == 'M': - return int(s[:-1]) * 1024 * 1024 - if 0 <= (ord(s[-1]) - ord('0')) <= 9: - return int(s) - assert 'not a number: %s' % s - -def parse_name(name): - if '<' not in name and '/' not in name and name not in bm_specs: - return {'name': name} - rest = name - out = {} - tpl_args = [] - dyn_args = [] - if '<' in rest: - tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')] - arg = '' - nesting = 0 - for c in tpl_bit: - if c == '<': - nesting += 1 - arg += c - elif c == '>': - nesting -= 1 - arg += c - elif c == ',': - if nesting == 0: - tpl_args.append(arg.strip()) - arg = '' - else: - arg += c - else: - arg += c - tpl_args.append(arg.strip()) - rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:] - if '/' in rest: - s = rest.split('/') - rest = s[0] - dyn_args = s[1:] - name = rest - assert name in bm_specs, 'bm_specs needs to be expanded for %s' % name - assert len(dyn_args) == len(bm_specs[name]['dyn']) - assert len(tpl_args) == len(bm_specs[name]['tpl']) - out['name'] = name - out.update(dict((k, numericalize(v)) for k, v in zip(bm_specs[name]['dyn'], dyn_args))) - out.update(dict(zip(bm_specs[name]['tpl'], tpl_args))) - return out +writer = csv.DictWriter(sys.stdout, [c for c,t in columns]) -for bm in js['benchmarks']: - context = js['context'] - if 'label' in bm: - labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#'] - for el in labels_list: - el[0] = el[0].replace('/iter', '_per_iteration') - labels = dict(labels_list) - else: - labels = {} - row = { - 'jenkins_build': os.environ.get('BUILD_NUMBER', ''), - 'jenkins_job': os.environ.get('JOB_NAME', ''), - } - row.update(context) - row.update(bm) - row.update(parse_name(row['name'])) - row.update(labels) +for row in bm_json.expand_json(js, js2): if 'label' in row: del row['label'] + del row['cpp_name'] writer.writerow(row) diff --git a/tools/profiling/microbenchmarks/bm_diff.py b/tools/profiling/microbenchmarks/bm_diff.py new file mode 100755 index 00000000000..59cc2d0e475 --- /dev/null +++ b/tools/profiling/microbenchmarks/bm_diff.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python2.7 +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sys +import json +import bm_json +import tabulate + +with open(sys.argv[1]) as f: + js_new_ctr = json.loads(f.read()) +with open(sys.argv[2]) as f: + js_new_opt = json.loads(f.read()) +with open(sys.argv[3]) as f: + js_old_ctr = json.loads(f.read()) +with open(sys.argv[4]) as f: + js_old_opt = json.loads(f.read()) + +new = {} +old = {} + +for row in bm_json.expand_json(js_new_ctr, js_new_opt): + new[row['cpp_name']] = row +for row in bm_json.expand_json(js_old_ctr, js_old_opt): + old[row['cpp_name']] = row + +def changed_ratio(n, o): + return float(n-o)/float(o) + +def min_change(pct): + return lambda n, o: abs(changed_ratio(n,o)) > pct/100.0 + +_INTERESTING = ( + ('cpu_time', min_change(10)), + ('real_time', min_change(10)), + ('locks_per_iteration', min_change(5)), + ('allocs_per_iteration', min_change(5)), + ('writes_per_iteration', min_change(5)), + ('atm_cas_per_iteration', min_change(1)), + ('atm_add_per_iteration', min_change(5)), +) + +changed = [] +for fld, chk in _INTERESTING: + for bm in new.keys(): + if bm not in old: continue + n = new[bm] + o = old[bm] + if fld not in n or fld not in o: continue + if chk(n[fld], o[fld]): + changed.append((fld, chk)) + break + +headers = ['Benchmark'] + [c[0] for c in changed] + ['Details'] +rows = [] +for bm in sorted(new.keys()): + if bm not in old: continue + row = [bm] + any_changed = False + n = new[bm] + o = old[bm] + details = '' + for fld, chk in _INTERESTING: + if fld not in n or fld not in o: continue + if chk(n[fld], o[fld]): + row.append(changed_ratio(n[fld], o[fld])) + if details: details += ', ' + details += '%s:%r-->%r' % (fld, o[fld], n[fld]) + any_changed = True + else: + row.append('') + if any_changed: + row.append(details) + rows.append(row) +print tabulate.tabulate(rows, headers=headers, floatfmt='+.2f') diff --git a/tools/profiling/microbenchmarks/bm_json.py b/tools/profiling/microbenchmarks/bm_json.py new file mode 100644 index 00000000000..2548ed736f5 --- /dev/null +++ b/tools/profiling/microbenchmarks/bm_json.py @@ -0,0 +1,176 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os + +_BM_SPECS = { + 'BM_UnaryPingPong': { + 'tpl': ['fixture', 'client_mutator', 'server_mutator'], + 'dyn': ['request_size', 'response_size'], + }, + 'BM_PumpStreamClientToServer': { + 'tpl': ['fixture'], + 'dyn': ['request_size'], + }, + 'BM_PumpStreamServerToClient': { + 'tpl': ['fixture'], + 'dyn': ['request_size'], + }, + 'BM_StreamingPingPong': { + 'tpl': ['fixture', 'client_mutator', 'server_mutator'], + 'dyn': ['request_size', 'request_count'], + }, + 'BM_StreamingPingPongMsgs': { + 'tpl': ['fixture', 'client_mutator', 'server_mutator'], + 'dyn': ['request_size'], + }, + 'BM_PumpStreamServerToClient_Trickle': { + 'tpl': [], + 'dyn': ['request_size', 'bandwidth_kilobits'], + }, + 'BM_ErrorStringOnNewError': { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_ErrorStringRepeatedly': { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_ErrorGetStatus': { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_ErrorGetStatusCode': { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_ErrorHttpError': { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_HasClearGrpcStatus': { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_IsolatedFilter' : { + 'tpl': ['fixture', 'client_mutator'], + 'dyn': [], + }, + 'BM_HpackEncoderEncodeHeader' : { + 'tpl': ['fixture'], + 'dyn': ['end_of_stream', 'request_size'], + }, + 'BM_HpackParserParseHeader' : { + 'tpl': ['fixture'], + 'dyn': [], + }, + 'BM_CallCreateDestroy' : { + 'tpl': ['fixture'], + 'dyn': [], + }, +} + +def numericalize(s): + if not s: return '' + if s[-1] == 'k': + return int(s[:-1]) * 1024 + if s[-1] == 'M': + return int(s[:-1]) * 1024 * 1024 + if 0 <= (ord(s[-1]) - ord('0')) <= 9: + return int(s) + assert 'not a number: %s' % s + +def parse_name(name): + cpp_name = name + if '<' not in name and '/' not in name and name not in _BM_SPECS: + return {'name': name, 'cpp_name': name} + rest = name + out = {} + tpl_args = [] + dyn_args = [] + if '<' in rest: + tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')] + arg = '' + nesting = 0 + for c in tpl_bit: + if c == '<': + nesting += 1 + arg += c + elif c == '>': + nesting -= 1 + arg += c + elif c == ',': + if nesting == 0: + tpl_args.append(arg.strip()) + arg = '' + else: + arg += c + else: + arg += c + tpl_args.append(arg.strip()) + rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:] + if '/' in rest: + s = rest.split('/') + rest = s[0] + dyn_args = s[1:] + name = rest + assert name in _BM_SPECS, '_BM_SPECS needs to be expanded for %s' % name + assert len(dyn_args) == len(_BM_SPECS[name]['dyn']) + assert len(tpl_args) == len(_BM_SPECS[name]['tpl']) + out['name'] = name + out['cpp_name'] = cpp_name + out.update(dict((k, numericalize(v)) for k, v in zip(_BM_SPECS[name]['dyn'], dyn_args))) + out.update(dict(zip(_BM_SPECS[name]['tpl'], tpl_args))) + return out + +def expand_json(js, js2 = None): + for bm in js['benchmarks']: + context = js['context'] + if 'label' in bm: + labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#'] + for el in labels_list: + el[0] = el[0].replace('/iter', '_per_iteration') + labels = dict(labels_list) + else: + labels = {} + row = { + 'jenkins_build': os.environ.get('BUILD_NUMBER', ''), + 'jenkins_job': os.environ.get('JOB_NAME', ''), + } + row.update(context) + row.update(bm) + row.update(parse_name(row['name'])) + row.update(labels) + if js2: + for bm2 in js2['benchmarks']: + if bm['name'] == bm2['name']: + row['cpu_time'] = bm2['cpu_time'] + row['real_time'] = bm2['real_time'] + row['iterations'] = bm2['iterations'] + yield row diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 15bcf5621e3..767c2b2e368 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -421,6 +421,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "error_test", + "src": [ + "test/core/iomgr/error_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -1657,6 +1674,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "parse_address_test", + "src": [ + "test/core/client_channel/parse_address_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -2032,6 +2066,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "stream_owned_slice_test", + "src": [ + "test/core/transport/stream_owned_slice_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -2386,6 +2437,7 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], @@ -2406,6 +2458,7 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], @@ -2426,6 +2479,7 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], @@ -2446,6 +2500,7 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], @@ -2466,6 +2521,7 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], @@ -2486,14 +2542,15 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], "is_filegroup": false, "language": "c++", - "name": "bm_fullstack", + "name": "bm_fullstack_streaming_ping_pong", "src": [ - "test/cpp/microbenchmarks/bm_fullstack.cc" + "test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc" ], "third_party": false, "type": "target" @@ -2504,6 +2561,72 @@ "gpr", "gpr_test_util", "grpc", + "grpc++", + "grpc++_test_util", + "grpc_benchmark", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_fullstack_streaming_pump", + "src": [ + "test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_benchmark", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_fullstack_trickle", + "src": [ + "test/cpp/microbenchmarks/bm_fullstack_trickle.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_benchmark", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_fullstack_unary_ping_pong", + "src": [ + "test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_benchmark", "grpc_test_util" ], "headers": [], @@ -3455,6 +3578,30 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [ + "src/proto/grpc/testing/echo.grpc.pb.h", + "src/proto/grpc/testing/echo.pb.h", + "src/proto/grpc/testing/echo_messages.grpc.pb.h", + "src/proto/grpc/testing/echo_messages.pb.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "server_builder_test", + "src": [ + "test/cpp/server/server_builder_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5707,6 +5854,30 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "benchmark", + "grpc", + "grpc++", + "grpc_test_util" + ], + "headers": [ + "test/cpp/microbenchmarks/fullstack_context_mutators.h", + "test/cpp/microbenchmarks/fullstack_fixtures.h", + "test/cpp/microbenchmarks/helpers.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "grpc_benchmark", + "src": [ + "test/cpp/microbenchmarks/fullstack_context_mutators.h", + "test/cpp/microbenchmarks/fullstack_fixtures.h", + "test/cpp/microbenchmarks/helpers.cc", + "test/cpp/microbenchmarks/helpers.h" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "grpc++", @@ -7912,7 +8083,7 @@ "headers": [ "test/core/end2end/cq_verifier.h", "test/core/end2end/fake_resolver.h", - "test/core/end2end/fixtures/http_proxy.h", + "test/core/end2end/fixtures/http_proxy_fixture.h", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", @@ -7934,8 +8105,8 @@ "test/core/end2end/cq_verifier.h", "test/core/end2end/fake_resolver.c", "test/core/end2end/fake_resolver.h", - "test/core/end2end/fixtures/http_proxy.c", - "test/core/end2end/fixtures/http_proxy.h", + "test/core/end2end/fixtures/http_proxy_fixture.c", + "test/core/end2end/fixtures/http_proxy_fixture.h", "test/core/end2end/fixtures/proxy.c", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.c", @@ -7952,12 +8123,10 @@ "test/core/util/parse_hexstring.h", "test/core/util/passthru_endpoint.c", "test/core/util/passthru_endpoint.h", + "test/core/util/port.c", "test/core/util/port.h", - "test/core/util/port_posix.c", "test/core/util/port_server_client.c", "test/core/util/port_server_client.h", - "test/core/util/port_uv.c", - "test/core/util/port_windows.c", "test/core/util/slice_splitter.c", "test/core/util/slice_splitter.h", "test/core/util/trickle_endpoint.c", @@ -8253,6 +8422,7 @@ "include/grpc++/grpc++.h", "include/grpc++/health_check_service_interface.h", "include/grpc++/impl/call.h", + "include/grpc++/impl/channel_argument_option.h", "include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/codegen/core_codegen.h", "include/grpc++/impl/grpc_library.h", @@ -8309,6 +8479,7 @@ "include/grpc++/grpc++.h", "include/grpc++/health_check_service_interface.h", "include/grpc++/impl/call.h", + "include/grpc++/impl/channel_argument_option.h", "include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/codegen/core_codegen.h", "include/grpc++/impl/grpc_library.h", @@ -8358,6 +8529,7 @@ "src/cpp/common/rpc_method.cc", "src/cpp/common/version_cc.cc", "src/cpp/server/async_generic_service.cc", + "src/cpp/server/channel_argument_option.cc", "src/cpp/server/create_default_thread_pool.cc", "src/cpp/server/dynamic_thread_pool.cc", "src/cpp/server/dynamic_thread_pool.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index eca65ac5334..f9e2a19d0ef 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -515,6 +515,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 30, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "error_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -1719,6 +1741,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "parse_address_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -2115,6 +2159,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "stream_owned_slice_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -2668,7 +2734,88 @@ "flaky": false, "gtest": false, "language": "c++", - "name": "bm_fullstack", + "name": "bm_fullstack_streaming_ping_pong", + "platforms": [ + "linux", + "mac", + "posix" + ], + "timeout_seconds": 1200 + }, + { + "args": [ + "--benchmark_min_time=0" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "excluded_poll_engines": [ + "poll", + "poll-cv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_fullstack_streaming_pump", + "platforms": [ + "linux", + "mac", + "posix" + ], + "timeout_seconds": 1200 + }, + { + "args": [ + "--benchmark_min_time=0" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "excluded_poll_engines": [ + "poll", + "poll-cv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_fullstack_trickle", + "platforms": [ + "linux", + "mac", + "posix" + ], + "timeout_seconds": 1200 + }, + { + "args": [ + "--benchmark_min_time=0" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "excluded_poll_engines": [ + "poll", + "poll-cv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_fullstack_unary_ping_pong", "platforms": [ "linux", "mac", @@ -3005,7 +3152,9 @@ ] }, { - "args": [], + "args": [ + "--generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h" + ], "ci_platforms": [ "linux", "mac", @@ -3350,6 +3499,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "server_builder_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -80536,6 +80707,50 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5834320218423296" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "api_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "api_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-0597bbdd657fa4ed14443994c9147a1a7bbc205f" diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.bat b/tools/run_tests/helper_scripts/pre_build_csharp.bat index f37f63b5840..99df1c66268 100644 --- a/tools/run_tests/helper_scripts/pre_build_csharp.bat +++ b/tools/run_tests/helper_scripts/pre_build_csharp.bat @@ -89,18 +89,6 @@ if exist %NUGET% ( %NUGET% restore -PackagesDirectory ../packages || goto :error cd .. - cd Grpc.IntegrationTesting.Client || goto :error - %NUGET% restore -PackagesDirectory ../packages || goto :error - cd .. - - cd Grpc.IntegrationTesting.QpsWorker || goto :error - %NUGET% restore -PackagesDirectory ../packages || goto :error - cd .. - - cd Grpc.IntegrationTesting.StressClient || goto :error - %NUGET% restore -PackagesDirectory ../packages || goto :error - cd .. - cd Grpc.IntegrationTesting || goto :error %NUGET% restore -PackagesDirectory ../packages || goto :error diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.sh b/tools/run_tests/helper_scripts/pre_build_csharp.sh index 1f808556f48..d7665e15af6 100755 --- a/tools/run_tests/helper_scripts/pre_build_csharp.sh +++ b/tools/run_tests/helper_scripts/pre_build_csharp.sh @@ -73,18 +73,6 @@ then nuget restore -PackagesDirectory ../packages cd .. - cd Grpc.IntegrationTesting.Client - nuget restore -PackagesDirectory ../packages - cd .. - - cd Grpc.IntegrationTesting.QpsWorker - nuget restore -PackagesDirectory ../packages - cd .. - - cd Grpc.IntegrationTesting.StressClient - nuget restore -PackagesDirectory ../packages - cd .. - cd Grpc.IntegrationTesting nuget restore -PackagesDirectory ../packages cd .. diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 865125fcd78..830b8c0849d 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -413,11 +413,12 @@ class NodeLanguage: client_type='ASYNC_CLIENT', server_type='async_server', client_language='c++') - yield _ping_pong_scenario( - 'node_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY', - client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', - unconstrained_client='async', - categories=[SCALABLE, SMOKETEST]) + # TODO(murgatroid99): fix bugs with this scenario and re-enable it + # yield _ping_pong_scenario( + # 'node_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY', + # client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', + # unconstrained_client='async', + # categories=[SCALABLE, SMOKETEST]) # TODO(jtattermusch): make this scenario work #yield _ping_pong_scenario( diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py index 7b2c62d1a2b..5d812f28ee9 100755 --- a/tools/run_tests/python_utils/jobset.py +++ b/tools/run_tests/python_utils/jobset.py @@ -31,6 +31,7 @@ from __future__ import print_function +import logging import multiprocessing import os import platform @@ -128,6 +129,8 @@ _TAG_COLOR = { 'SKIPPED': 'cyan' } +_FORMAT = '%(asctime)-15s %(message)s' +logging.basicConfig(level=logging.INFO, format=_FORMAT) def message(tag, msg, explanatory_text=None, do_newline=False): if message.old_tag == tag and message.old_msg == msg and not explanatory_text: @@ -137,8 +140,8 @@ def message(tag, msg, explanatory_text=None, do_newline=False): try: if platform_string() == 'windows' or not sys.stdout.isatty(): if explanatory_text: - print(explanatory_text) - print('%s: %s' % (tag, msg)) + logging.info(explanatory_text) + logging.info('%s: %s', tag, msg) else: sys.stdout.write('%s%s%s\x1b[%d;%dm%s\x1b[0m: %s%s' % ( _BEGINNING_OF_LINE, @@ -473,13 +476,13 @@ def run(cmdlines, skip_jobs=False, quiet_success=False): if skip_jobs: - results = {} + resultset = {} skipped_job_result = JobResult() skipped_job_result.state = 'SKIPPED' for job in cmdlines: message('SKIPPED', job.shortname, do_newline=True) - results[job.shortname] = [skipped_job_result] - return results + resultset[job.shortname] = [skipped_job_result] + return 0, resultset js = Jobset(check_cancelled, maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS, newline_on_success, travis, stop_on_failure, add_env, diff --git a/tools/run_tests/python_utils/start_port_server.py b/tools/run_tests/python_utils/start_port_server.py index 4c9f6aac639..deb73544388 100644 --- a/tools/run_tests/python_utils/start_port_server.py +++ b/tools/run_tests/python_utils/start_port_server.py @@ -40,7 +40,10 @@ import tempfile import time -def start_port_server(port_server_port): +# must be synchronized with test/core/utils/port_server_client.h +_PORT_SERVER_PORT = 32766 + +def start_port_server(): # check if a compatible port server is running # if incompatible (version mismatch) ==> start a new one # if not running ==> start a new one @@ -48,7 +51,7 @@ def start_port_server(port_server_port): try: version = int( urllib.request.urlopen( - 'http://localhost:%d/version_number' % port_server_port, + 'http://localhost:%d/version_number' % _PORT_SERVER_PORT, timeout=10).read()) logging.info('detected port server running version %d', version) running = True @@ -67,7 +70,7 @@ def start_port_server(port_server_port): if not running: logging.info('port_server version mismatch: killing the old one') urllib.request.urlopen('http://localhost:%d/quitquitquit' % - port_server_port).read() + _PORT_SERVER_PORT).read() time.sleep(1) if not running: fd, logfile = tempfile.mkstemp() @@ -76,7 +79,7 @@ def start_port_server(port_server_port): args = [ sys.executable, os.path.abspath('tools/run_tests/python_utils/port_server.py'), - '-p', '%d' % port_server_port, '-l', logfile + '-p', '%d' % _PORT_SERVER_PORT, '-l', logfile ] env = dict(os.environ) env['BUILD_ID'] = 'pleaseDontKillMeJenkins' @@ -107,7 +110,7 @@ def start_port_server(port_server_port): time.sleep(1) try: urllib.request.urlopen( - 'http://localhost:%d/get' % port_server_port, + 'http://localhost:%d/get' % _PORT_SERVER_PORT, timeout=1).read() logging.info( 'last ditch attempt to contact port server succeeded') @@ -119,7 +122,7 @@ def start_port_server(port_server_port): print(port_log) sys.exit(1) try: - port_server_url = 'http://localhost:%d/get' % port_server_port + port_server_url = 'http://localhost:%d/get' % _PORT_SERVER_PORT urllib.request.urlopen(port_server_url, timeout=1).read() logging.info('port server is up and ready') break diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index eccfe41dc0e..161fa81956b 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -77,11 +77,15 @@ class CXXLanguage: def __init__(self): self.client_cwd = None self.server_cwd = None + self.http2_cwd = None self.safename = 'cxx' def client_cmd(self, args): return ['bins/opt/interop_client'] + args + def client_cmd_http2interop(self, args): + return ['bins/opt/http2_client'] + args + def cloud_to_prod_env(self): return {} @@ -474,8 +478,7 @@ _HTTP2_TEST_CASES = ['tls', 'framing'] _HTTP2_BADSERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data', 'goaway', 'ping', 'max_streams'] -# TODO: Add python once the tests are fixed. -_LANGUAGES_FOR_HTTP2_BADSERVER_TESTS = ['java', 'go'] +_LANGUAGES_FOR_HTTP2_BADSERVER_TESTS = ['java', 'go', 'python', 'c++'] DOCKER_WORKDIR_ROOT = '/var/local/git/grpc' @@ -498,6 +501,28 @@ def docker_run_cmdline(cmdline, image, docker_args=[], cwd=None, environ=None): return docker_cmdline +def manual_cmdline(docker_cmdline): + """Returns docker cmdline adjusted for manual invocation.""" + print_cmdline = [] + for item in docker_cmdline: + if item.startswith('--name='): + continue + # add quotes when necessary + if any(character.isspace() for character in item): + item = "\"%s\"" % item + print_cmdline.append(item) + return ' '.join(print_cmdline) + + +def write_cmdlog_maybe(cmdlog, filename): + """Returns docker cmdline adjusted for manual invocation.""" + if cmdlog: + with open(filename, 'w') as logfile: + logfile.write('#!/bin/bash\n') + logfile.writelines("%s\n" % line for line in cmdlog) + print('Command log written to file %s' % filename) + + def bash_cmdline(cmdline): """Creates bash -c cmdline from args list.""" # Use login shell: @@ -548,7 +573,8 @@ def _job_kill_handler(job): def cloud_to_prod_jobspec(language, test_case, server_host_name, - server_host_detail, docker_image=None, auth=False): + server_host_detail, docker_image=None, auth=False, + manual_cmd_log=None): """Creates jobspec for cloud-to-prod interop test""" container_name = None cmdargs = [ @@ -573,7 +599,9 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name, cwd=cwd, environ=environ, docker_args=['--net=host', - '--name', container_name]) + '--name=%s' % container_name]) + if manual_cmd_log is not None: + manual_cmd_log.append(manual_cmdline(cmdline)) cwd = None environ = None @@ -594,7 +622,8 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name, def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, - server_port, docker_image=None, insecure=False): + server_port, docker_image=None, insecure=False, + manual_cmd_log=None): """Creates jobspec for cloud-to-cloud interop test""" interop_only_options = [ '--server_host_override=foo.test.google.fr', @@ -625,7 +654,9 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, environ=environ, cwd=cwd, docker_args=['--net=host', - '--name', container_name]) + '--name=%s' % container_name]) + if manual_cmd_log is not None: + manual_cmd_log.append(manual_cmdline(cmdline)) cwd = None test_job = jobset.JobSpec( @@ -643,7 +674,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, return test_job -def server_jobspec(language, docker_image, insecure=False): +def server_jobspec(language, docker_image, insecure=False, manual_cmd_log=None): """Create jobspec for running a server""" container_name = dockerjob.random_name('interop_server_%s' % language.safename) cmdline = bash_cmdline( @@ -673,7 +704,9 @@ def server_jobspec(language, docker_image, insecure=False): cwd=language.server_cwd, environ=environ, docker_args=port_args + - ['--name', container_name]) + ['--name=%s' % container_name]) + if manual_cmd_log is not None: + manual_cmd_log.append(manual_cmdline(docker_cmdline)) server_job = jobset.JobSpec( cmdline=docker_cmdline, environ=environ, @@ -803,6 +836,14 @@ argp.add_argument('--allow_flakes', action='store_const', const=True, help='Allow flaky tests to show as passing (re-runs failed tests up to five times)') +argp.add_argument('--manual_run', + default=False, + action='store_const', + const=True, + help='Prepare things for running interop tests manually. ' + + 'Preserve docker images after building them and skip ' + 'actually running the tests. Only print commands to run by ' + + 'hand.') argp.add_argument('--http2_interop', default=False, action='store_const', @@ -834,6 +875,10 @@ if args.use_docker: print('copied to the docker environment.') time.sleep(5) +if args.manual_run and not args.use_docker: + print('--manual_run is only supported with --use_docker option enabled.') + sys.exit(1) + if not args.use_docker and servers: print('Running interop servers is only supported with --use_docker option enabled.') sys.exit(1) @@ -884,24 +929,36 @@ if args.use_docker: dockerjob.remove_image(image, skip_nonexistent=True) sys.exit(1) +server_manual_cmd_log = [] if args.manual_run else None +client_manual_cmd_log = [] if args.manual_run else None + # Start interop servers. -server_jobs={} -server_addresses={} +server_jobs = {} +server_addresses = {} try: for s in servers: lang = str(s) spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang), - args.insecure) - job = dockerjob.DockerJob(spec) - server_jobs[lang] = job - server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT)) + args.insecure, manual_cmd_log=server_manual_cmd_log) + if not args.manual_run: + job = dockerjob.DockerJob(spec) + server_jobs[lang] = job + server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT)) + else: + # don't run the server, set server port to a placeholder value + server_addresses[lang] = ('localhost', '${SERVER_PORT}') if args.http2_badserver_interop: # launch a HTTP2 server emulator that creates edge cases lang = str(http2InteropServer) - spec = server_jobspec(http2InteropServer, docker_images.get(lang)) - job = dockerjob.DockerJob(spec) - server_jobs[lang] = job + spec = server_jobspec(http2InteropServer, docker_images.get(lang), + manual_cmd_log=server_manual_cmd_log) + if not args.manual_run: + job = dockerjob.DockerJob(spec) + server_jobs[lang] = job + else: + # don't run the server, set server port to a placeholder value + server_addresses[lang] = ('localhost', '${SERVER_PORT}') jobs = [] if args.cloud_to_prod: @@ -915,7 +972,8 @@ try: test_job = cloud_to_prod_jobspec( language, test_case, server_host_name, prod_servers[server_host_name], - docker_image=docker_images.get(str(language))) + docker_image=docker_images.get(str(language)), + manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) if args.http2_interop: @@ -923,7 +981,8 @@ try: test_job = cloud_to_prod_jobspec( http2Interop, test_case, server_host_name, prod_servers[server_host_name], - docker_image=docker_images.get(str(http2Interop))) + docker_image=docker_images.get(str(http2Interop)), + manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) if args.cloud_to_prod_auth: @@ -936,7 +995,8 @@ try: test_job = cloud_to_prod_jobspec( language, test_case, server_host_name, prod_servers[server_host_name], - docker_image=docker_images.get(str(language)), auth=True) + docker_image=docker_images.get(str(language)), auth=True, + manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) for server in args.override_server: @@ -960,7 +1020,8 @@ try: server_host, server_port, docker_image=docker_images.get(str(language)), - insecure=args.insecure) + insecure=args.insecure, + manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) if args.http2_interop: @@ -974,7 +1035,8 @@ try: server_host, server_port, docker_image=docker_images.get(str(http2Interop)), - insecure=args.insecure) + insecure=args.insecure, + manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) if args.http2_badserver_interop: @@ -985,7 +1047,8 @@ try: str(http2InteropServer), 'localhost', _DEFAULT_SERVER_PORT, - docker_image=docker_images.get(str(language))) + docker_image=docker_images.get(str(language)), + manual_cmd_log=client_manual_cmd_log) jobs.append(test_job) if not jobs: @@ -994,13 +1057,20 @@ try: dockerjob.remove_image(image, skip_nonexistent=True) sys.exit(1) + if args.manual_run: + print('All tests will skipped --manual_run option is active.') + num_failures, resultset = jobset.run(jobs, newline_on_success=True, - maxjobs=args.jobs) + maxjobs=args.jobs, + skip_jobs=args.manual_run) if num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) else: jobset.message('SUCCESS', 'All tests passed', do_newline=True) + write_cmdlog_maybe(server_manual_cmd_log, 'interop_server_cmds.sh') + write_cmdlog_maybe(client_manual_cmd_log, 'interop_client_cmds.sh') + report_utils.render_junit_xml_report(resultset, 'report.xml') for name, job in resultset.items(): @@ -1026,5 +1096,8 @@ finally: dockerjob.finish_jobs([j for j in server_jobs.itervalues()]) for image in docker_images.itervalues(): - print('Removing docker image %s' % image) - dockerjob.remove_image(image) + if not args.manual_run: + print('Removing docker image %s' % image) + dockerjob.remove_image(image) + else: + print('Preserving docker image: %s' % image) diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py index 4307906a7e4..f41bde113a8 100755 --- a/tools/run_tests/run_microbenchmark.py +++ b/tools/run_tests/run_microbenchmark.py @@ -44,8 +44,7 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../..')) if not os.path.exists('reports'): os.makedirs('reports') -port_server_port = 32766 -start_port_server.start_port_server(port_server_port) +start_port_server.start_port_server() def fnize(s): out = '' @@ -110,8 +109,7 @@ def collect_latency(bm_name, args): if len(benchmarks) >= min(16, multiprocessing.cpu_count()): # run up to half the cpu count: each benchmark can use up to two cores # (one for the microbenchmark, one for the data flush) - jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2), - add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port}) + jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2)) jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count()) jobset.run(cleanup, maxjobs=multiprocessing.cpu_count()) benchmarks = [] @@ -119,8 +117,7 @@ def collect_latency(bm_name, args): cleanup = [] # run the remaining benchmarks that weren't flushed if len(benchmarks): - jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2), - add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port}) + jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2)) jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count()) jobset.run(cleanup, maxjobs=multiprocessing.cpu_count()) @@ -156,8 +153,7 @@ def collect_perf(bm_name, args): if len(benchmarks) >= 20: # run up to half the cpu count: each benchmark can use up to two cores # (one for the microbenchmark, one for the data flush) - jobset.run(benchmarks, maxjobs=1, - add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port}) + jobset.run(benchmarks, maxjobs=1) jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count()) jobset.run(cleanup, maxjobs=multiprocessing.cpu_count()) benchmarks = [] @@ -165,26 +161,32 @@ def collect_perf(bm_name, args): cleanup = [] # run the remaining benchmarks that weren't flushed if len(benchmarks): - jobset.run(benchmarks, maxjobs=1, - add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port}) + jobset.run(benchmarks, maxjobs=1) jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count()) jobset.run(cleanup, maxjobs=multiprocessing.cpu_count()) -def collect_summary(bm_name, args): - heading('Summary: %s' % bm_name) +def run_summary(bm_name, cfg, base_json_name): subprocess.check_call( ['make', bm_name, - 'CONFIG=counters', '-j', '%d' % multiprocessing.cpu_count()]) - cmd = ['bins/counters/%s' % bm_name, - '--benchmark_out=out.json', + 'CONFIG=%s' % cfg, '-j', '%d' % multiprocessing.cpu_count()]) + cmd = ['bins/%s/%s' % (cfg, bm_name), + '--benchmark_out=%s.%s.json' % (base_json_name, cfg), '--benchmark_out_format=json'] if args.summary_time is not None: cmd += ['--benchmark_min_time=%d' % args.summary_time] - text(subprocess.check_output(cmd)) + return subprocess.check_output(cmd) + +def collect_summary(bm_name, args): + heading('Summary: %s [no counters]' % bm_name) + text(run_summary(bm_name, 'opt', bm_name)) + heading('Summary: %s [with counters]' % bm_name) + text(run_summary(bm_name, 'counters', bm_name)) if args.bigquery_upload: - with open('out.csv', 'w') as f: - f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', 'out.json'])) - subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', 'out.csv']) + with open('%s.csv' % bm_name, 'w') as f: + f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', + '%s.counters.json' % bm_name, + '%s.opt.json' % bm_name])) + subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', '%s.csv' % bm_name]) collectors = { 'latency': collect_latency, @@ -195,20 +197,28 @@ collectors = { argp = argparse.ArgumentParser(description='Collect data from microbenchmarks') argp.add_argument('-c', '--collect', choices=sorted(collectors.keys()), - nargs='+', + nargs='*', default=sorted(collectors.keys()), help='Which collectors should be run against each benchmark') argp.add_argument('-b', '--benchmarks', - default=['bm_fullstack', + default=['bm_fullstack_unary_ping_pong', + 'bm_fullstack_streaming_ping_pong', + 'bm_fullstack_streaming_pump', 'bm_closure', 'bm_cq', 'bm_call_create', 'bm_error', 'bm_chttp2_hpack', - 'bm_metadata'], + 'bm_metadata', + 'bm_fullstack_trickle', + ], nargs='+', type=str, help='Which microbenchmarks should be run') +argp.add_argument('--diff_perf', + default=None, + type=str, + help='Diff microbenchmarks against this git revision') argp.add_argument('--bigquery_upload', default=False, action='store_const', @@ -220,10 +230,39 @@ argp.add_argument('--summary_time', help='Minimum time to run benchmarks for the summary collection') args = argp.parse_args() -for bm_name in args.benchmarks: - for collect in args.collect: - collectors[collect](bm_name, args) - -index_html += "\n\n" -with open('reports/index.html', 'w') as f: - f.write(index_html) +try: + for bm_name in args.benchmarks: + for collect in args.collect: + collectors[collect](bm_name, args) + if args.diff_perf: + if 'summary' not in args.collect: + for bm_name in args.benchmarks: + run_summary(bm_name, 'opt', bm_name) + run_summary(bm_name, 'counters', bm_name) + where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip() + subprocess.check_call(['git', 'checkout', args.diff_perf]) + comparables = [] + subprocess.check_call(['make', 'clean']) + try: + for bm_name in args.benchmarks: + try: + run_summary(bm_name, 'opt', '%s.old' % bm_name) + run_summary(bm_name, 'counters', '%s.old' % bm_name) + comparables.append(bm_name) + except subprocess.CalledProcessError, e: + pass + finally: + subprocess.check_call(['git', 'checkout', where_am_i]) + for bm_name in comparables: + diff = subprocess.check_output(['tools/profiling/microbenchmarks/bm_diff.py', + '%s.counters.json' % bm_name, + '%s.opt.json' % bm_name, + '%s.old.counters.json' % bm_name, + '%s.old.opt.json' % bm_name]).strip() + if diff: + heading('Performance diff: %s' % bm_name) + text(diff) +finally: + index_html += "\n\n" + with open('reports/index.html', 'w') as f: + f.write(index_html) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index 7c04d228ba3..ee4102c5913 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -101,7 +101,7 @@ def create_qpsworker_job(language, shortname=None, port=10000, remote_host=None, user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host) ssh_cmd = ['ssh'] cmdline = ['timeout', '%s' % (worker_timeout + 30)] + cmdline - ssh_cmd.extend([str(user_at_host), 'cd ~/performance_workspace/grpc/ && %s' % ' '.join(cmdline)]) + ssh_cmd.extend([str(user_at_host), 'cd ~/performance_workspace/grpc/ && tools/run_tests/start_port_server.py && %s' % ' '.join(cmdline)]) cmdline = ssh_cmd jobspec = jobset.JobSpec( diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 9e9af59c254..43b8f8184e2 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -307,9 +307,9 @@ class CLanguage(object): assert base is not None assert line[1] == ' ' test = base + line.strip() - cmdline = [binary] + ['--gtest_filter=%s' % test] + cmdline = [binary, '--gtest_filter=%s' % test] + target['args'] out.append(self.config.job_spec(cmdline, - shortname='%s --gtest_filter=%s %s' % (binary, test, shortname_ext), + shortname='%s %s' % (' '.join(cmdline), shortname_ext), cpu_cost=cpu_cost, timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling, environ=env)) @@ -692,18 +692,11 @@ class RubyLanguage(object): _check_compiler(self.args.compiler, ['default']) def test_specs(self): - #TODO(apolcyn) turn mac ruby tests back on once ruby 2.4 issues done - if platform_string() == 'mac': - print('skipping ruby test_specs on mac until running on 2.4') - return [] return [self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby.sh'], timeout_seconds=10*60, environ=_FORCE_ENVIRON_FOR_WRAPPERS)] def pre_build_steps(self): - if platform_string() == 'mac': - print('skipping ruby pre_build_steps on mac until running on 2.4') - return [] return [['tools/run_tests/helper_scripts/pre_build_ruby.sh']] def make_targets(self): @@ -713,15 +706,9 @@ class RubyLanguage(object): return [] def build_steps(self): - if platform_string() == 'mac': - print('skipping ruby build_steps on mac until running on 2.4') - return [] return [['tools/run_tests/helper_scripts/build_ruby.sh']] def post_tests_steps(self): - if platform_string() == 'mac': - print('skipping ruby post_test_steps on mac until running on 2.4') - return [] return [['tools/run_tests/helper_scripts/post_tests_ruby.sh']] def makefile_name(self): @@ -1311,7 +1298,9 @@ if args.use_docker: if not args.travis: env['TTY_FLAG'] = '-t' # enables Ctrl-C when not on Jenkins. - run_shell_command('tools/run_tests/dockerize/build_docker_and_run_tests.sh', env=env) + subprocess.check_call('tools/run_tests/dockerize/build_docker_and_run_tests.sh', + shell=True, + env=env) sys.exit(0) _check_arch_option(args.arch) @@ -1451,8 +1440,7 @@ def _build_and_run( # start antagonists antagonists = [subprocess.Popen(['tools/run_tests/python_utils/antagonist.py']) for _ in range(0, args.antagonists)] - port_server_port = 32766 - start_port_server.start_port_server(port_server_port) + start_port_server.start_port_server() resultset = None num_test_failures = 0 try: @@ -1479,10 +1467,9 @@ def _build_and_run( sample_size = int(num_jobs * args.sample_percent/100.0) massaged_one_run = random.sample(massaged_one_run, sample_size) if not isclose(args.sample_percent, 100.0): + assert args.runs_per_test == 1, "Can't do sampling (-p) over multiple runs (-n)." print("Running %d tests out of %d (~%d%%)" % (sample_size, num_jobs, args.sample_percent)) - else: - assert args.runs_per_test == 1, "Can't do sampling (-p) over multiple runs (-n)." if infinite_runs: assert len(massaged_one_run) > 0, 'Must have at least one test for a -n inf run' runs_sequence = (itertools.repeat(massaged_one_run) if infinite_runs @@ -1495,7 +1482,6 @@ def _build_and_run( all_runs, check_cancelled, newline_on_success=newline_on_success, travis=args.travis, maxjobs=args.jobs, stop_on_failure=args.stop_on_failure, - add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port}, quiet_success=args.quiet_success) if resultset: for k, v in sorted(resultset.items()): diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index bc4fdaba71e..47422451f8d 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -49,6 +49,9 @@ _RUNTESTS_TIMEOUT = 4*60*60 # Number of jobs assigned to each run_tests.py instance _DEFAULT_INNER_JOBS = 2 +# report suffix is important for reports to get picked up by internal CI +_REPORT_SUFFIX = 'sponge_log.xml' + def _docker_jobspec(name, runtests_args=[], inner_jobs=_DEFAULT_INNER_JOBS): """Run a single instance of run_tests.py in a docker container""" @@ -57,7 +60,7 @@ def _docker_jobspec(name, runtests_args=[], inner_jobs=_DEFAULT_INNER_JOBS): '--use_docker', '-t', '-j', str(inner_jobs), - '-x', 'report_%s.xml' % name, + '-x', 'report_%s_%s' % (name, _REPORT_SUFFIX), '--report_suite_name', '%s' % name] + runtests_args, shortname='run_tests_%s' % name, timeout_seconds=_RUNTESTS_TIMEOUT) @@ -70,10 +73,11 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_ workspace_name = 'workspace_%s' % name env = {'WORKSPACE_NAME': workspace_name} test_job = jobset.JobSpec( - cmdline=['tools/run_tests/helper_scripts/run_tests_in_workspace.sh', + cmdline=['bash', + 'tools/run_tests/helper_scripts/run_tests_in_workspace.sh', '-t', '-j', str(inner_jobs), - '-x', '../report_%s.xml' % name, + '-x', '../report_%s_%s' % (name, _REPORT_SUFFIX), '--report_suite_name', '%s' % name] + runtests_args, environ=env, shortname='run_tests_%s' % name, @@ -414,7 +418,7 @@ if __name__ == "__main__": skipped_results = jobset.run(skipped_jobs, skip_jobs=True) resultset.update(skipped_results) - report_utils.render_junit_xml_report(resultset, 'report.xml', + report_utils.render_junit_xml_report(resultset, 'report_%s' % _REPORT_SUFFIX, suite_name='aggregate_tests') if num_failures == 0: diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index cfe4e2731c0..3c5ba16b93b 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -46,7 +46,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules 886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7) 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0) c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0) - a428e42072765993ff674fda72863c9f1aa2d268 third_party/protobuf (v3.1.0-alpha-1) + 593e917c176b5bc5aafa57bf9f6030d749d91cd5 third_party/protobuf (v3.1.0-alpha-1-326-g593e917) bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift (bcad917) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) EOF diff --git a/tools/run_tests/start_port_server.py b/tools/run_tests/start_port_server.py new file mode 100755 index 00000000000..e33ac12bd3b --- /dev/null +++ b/tools/run_tests/start_port_server.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +Wrapper around port server starting code. + +Used by developers who wish to run individual C/C++ tests outside of the +run_tests.py infrastructure. + +The path to this file is called out in test/core/util/port.c, and printed as +an error message to users. +""" + +import python_utils.start_port_server as start_port_server + +start_port_server.start_port_server() + +print "Port server started successfully" diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index 623de48d3e7..daafd3f3504 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -297,6 +297,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endpoint_pair_test", "vcxpr {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "error_test", "vcxproj\test\error_test\error_test.vcxproj", "{42720233-A6D4-66BC-CCA2-06B57261D0B3}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fling_client", "vcxproj\test\fling_client\fling_client.vcxproj", "{0647D598-9611-F659-EA36-DF995C9F736B}" ProjectSection(myProperties) = preProject lib = "False" @@ -1264,6 +1275,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "no_server_test", "vcxproj\t {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parse_address_test", "vcxproj\test\parse_address_test\parse_address_test.vcxproj", "{EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "percent_encoding_test", "vcxproj\test\percent_encoding_test\percent_encoding_test.vcxproj", "{CCFC6A58-623D-9013-BFEB-C809809E2429}" ProjectSection(myProperties) = preProject lib = "False" @@ -1454,6 +1476,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "status_conversion_test", "v {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stream_owned_slice_test", "vcxproj\test\stream_owned_slice_test\stream_owned_slice_test.vcxproj", "{D5A20C05-D9B2-970B-8429-94BC3F58D1C4}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcp_client_uv_test", "vcxproj\test\tcp_client_uv_test\tcp_client_uv_test.vcxproj", "{9814D850-F3BB-8C7A-4C78-2751C1E272F4}" ProjectSection(myProperties) = preProject lib = "False" @@ -2043,6 +2076,22 @@ Global {37166D50-3AAA-1156-19F6-5901DFA55172}.Release-DLL|Win32.Build.0 = Release|Win32 {37166D50-3AAA-1156-19F6-5901DFA55172}.Release-DLL|x64.ActiveCfg = Release|x64 {37166D50-3AAA-1156-19F6-5901DFA55172}.Release-DLL|x64.Build.0 = Release|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|Win32.ActiveCfg = Debug|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|x64.ActiveCfg = Debug|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|Win32.ActiveCfg = Release|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|x64.ActiveCfg = Release|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|Win32.Build.0 = Debug|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug|x64.Build.0 = Debug|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|Win32.Build.0 = Release|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release|x64.Build.0 = Release|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Debug-DLL|x64.Build.0 = Debug|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|Win32.Build.0 = Release|Win32 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|x64.ActiveCfg = Release|x64 + {42720233-A6D4-66BC-CCA2-06B57261D0B3}.Release-DLL|x64.Build.0 = Release|x64 {0647D598-9611-F659-EA36-DF995C9F736B}.Debug|Win32.ActiveCfg = Debug|Win32 {0647D598-9611-F659-EA36-DF995C9F736B}.Debug|x64.ActiveCfg = Debug|x64 {0647D598-9611-F659-EA36-DF995C9F736B}.Release|Win32.ActiveCfg = Release|Win32 @@ -3515,6 +3564,22 @@ Global {A66AC548-E2B9-74CD-293C-43526EE51DCE}.Release-DLL|Win32.Build.0 = Release|Win32 {A66AC548-E2B9-74CD-293C-43526EE51DCE}.Release-DLL|x64.ActiveCfg = Release|x64 {A66AC548-E2B9-74CD-293C-43526EE51DCE}.Release-DLL|x64.Build.0 = Release|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|Win32.ActiveCfg = Debug|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|x64.ActiveCfg = Debug|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|Win32.ActiveCfg = Release|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|x64.ActiveCfg = Release|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|Win32.Build.0 = Debug|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug|x64.Build.0 = Debug|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|Win32.Build.0 = Release|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release|x64.Build.0 = Release|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Debug-DLL|x64.Build.0 = Debug|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|Win32.Build.0 = Release|Win32 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|x64.ActiveCfg = Release|x64 + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463}.Release-DLL|x64.Build.0 = Release|x64 {CCFC6A58-623D-9013-BFEB-C809809E2429}.Debug|Win32.ActiveCfg = Debug|Win32 {CCFC6A58-623D-9013-BFEB-C809809E2429}.Debug|x64.ActiveCfg = Debug|x64 {CCFC6A58-623D-9013-BFEB-C809809E2429}.Release|Win32.ActiveCfg = Release|Win32 @@ -3787,6 +3852,22 @@ Global {21E2A241-9D48-02CD-92E4-4EEC98424CF5}.Release-DLL|Win32.Build.0 = Release|Win32 {21E2A241-9D48-02CD-92E4-4EEC98424CF5}.Release-DLL|x64.ActiveCfg = Release|x64 {21E2A241-9D48-02CD-92E4-4EEC98424CF5}.Release-DLL|x64.Build.0 = Release|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|x64.ActiveCfg = Debug|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|Win32.ActiveCfg = Release|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|x64.ActiveCfg = Release|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|Win32.Build.0 = Debug|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug|x64.Build.0 = Debug|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|Win32.Build.0 = Release|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release|x64.Build.0 = Release|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Debug-DLL|x64.Build.0 = Debug|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|Win32.Build.0 = Release|Win32 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|x64.ActiveCfg = Release|x64 + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4}.Release-DLL|x64.Build.0 = Release|x64 {9814D850-F3BB-8C7A-4C78-2751C1E272F4}.Debug|Win32.ActiveCfg = Debug|Win32 {9814D850-F3BB-8C7A-4C78-2751C1E272F4}.Debug|x64.ActiveCfg = Debug|x64 {9814D850-F3BB-8C7A-4C78-2751C1E272F4}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index 45f3037e8ab..c85454a6dda 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -270,6 +270,7 @@ + @@ -414,6 +415,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index 95cdb7434c1..d800b297e9f 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -70,6 +70,9 @@ src\cpp\server + + src\cpp\server + src\cpp\server @@ -162,6 +165,9 @@ include\grpc++\impl + + include\grpc++\impl + include\grpc++\impl diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index 22ea361a02e..45c0ecd35d0 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -270,6 +270,7 @@ + @@ -398,6 +399,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index c3cef2d4df5..987d56d6a09 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -55,6 +55,9 @@ src\cpp\server + + src\cpp\server + src\cpp\server @@ -147,6 +150,9 @@ include\grpc++\impl + + include\grpc++\impl + include\grpc++\impl diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 6d4b4f70f16..e7c9fb71f33 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -182,7 +182,7 @@ - + @@ -317,7 +317,7 @@ - + @@ -335,14 +335,10 @@ - + - - - - diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index 5444f6f8c70..3d36948aaef 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -22,7 +22,7 @@ test\core\end2end - + test\core\end2end\fixtures @@ -49,18 +49,12 @@ test\core\util - + test\core\util test\core\util - - test\core\util - - - test\core\util - test\core\util @@ -524,7 +518,7 @@ test\core\end2end - + test\core\end2end\fixtures diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj index 1ea64654e5a..af13acef455 100644 --- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj @@ -149,7 +149,7 @@ - + @@ -168,7 +168,7 @@ - + @@ -186,14 +186,10 @@ - + - - - - diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters index e2ad88c96e1..4da043ea908 100644 --- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters @@ -7,7 +7,7 @@ test\core\end2end - + test\core\end2end\fixtures @@ -34,18 +34,12 @@ test\core\util - + test\core\util test\core\util - - test\core\util - - - test\core\util - test\core\util @@ -60,7 +54,7 @@ test\core\end2end - + test\core\end2end\fixtures diff --git a/vsprojects/vcxproj/test/error_test/error_test.vcxproj b/vsprojects/vcxproj/test/error_test/error_test.vcxproj new file mode 100644 index 00000000000..c7d0e5a1000 --- /dev/null +++ b/vsprojects/vcxproj/test/error_test/error_test.vcxproj @@ -0,0 +1,199 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {42720233-A6D4-66BC-CCA2-06B57261D0B3} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + error_test + static + Debug + static + Debug + + + error_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/error_test/error_test.vcxproj.filters b/vsprojects/vcxproj/test/error_test/error_test.vcxproj.filters new file mode 100644 index 00000000000..d2bb372482f --- /dev/null +++ b/vsprojects/vcxproj/test/error_test/error_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\core\iomgr + + + + + + {3226d467-9fe9-12e9-8b53-f24f5a4c34c0} + + + {3d86bf5c-b8eb-36f4-efe2-7e8596188481} + + + {91f383bc-92fa-7058-d971-20189eadc0ad} + + + + diff --git a/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj new file mode 100644 index 00000000000..58586f0cb8d --- /dev/null +++ b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj @@ -0,0 +1,206 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {31FCED31-7D88-BE3D-2D61-0840F08E0850} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + grpc_benchmark + static + Debug + static + Debug + + + grpc_benchmark + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + + + + + + + + + + {07978586-E47C-8709-A63E-895FBF3C3C7D} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj.filters b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj.filters new file mode 100644 index 00000000000..8e865bcc1bb --- /dev/null +++ b/vsprojects/vcxproj/test/grpc_benchmark/grpc_benchmark.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + test\cpp\microbenchmarks + + + + + test\cpp\microbenchmarks + + + test\cpp\microbenchmarks + + + test\cpp\microbenchmarks + + + + + + {46d1162d-13b8-d144-8b76-77a6d982a9f1} + + + {1d2b47d7-8fc3-a5b6-cc85-47e31600e9d7} + + + {2a1ac913-6c7b-fbd2-6e8f-1215e92b4af8} + + + + diff --git a/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj new file mode 100644 index 00000000000..17046708f92 --- /dev/null +++ b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj @@ -0,0 +1,199 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {EDEA8257-AEA8-1B0A-F95B-8D6CD7286463} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + parse_address_test + static + Debug + static + Debug + + + parse_address_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj.filters b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj.filters new file mode 100644 index 00000000000..e4e446da997 --- /dev/null +++ b/vsprojects/vcxproj/test/parse_address_test/parse_address_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\core\client_channel + + + + + + {1613c595-3fdf-b7ab-6d5f-667bbd7eefc7} + + + {cdfde21c-75c2-08ee-3d98-8ca67b5c31e0} + + + {60d8328d-ca06-b3cf-cf1d-889b6677def1} + + + + diff --git a/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj new file mode 100644 index 00000000000..ebbfd59f3d3 --- /dev/null +++ b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj @@ -0,0 +1,223 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {60523734-00BD-765B-5A5B-19E19A2E31B8} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + server_builder_test + static + Debug + static + Debug + + + server_builder_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + {0BE77741-552A-929B-A497-4EF7ECE17A64} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters new file mode 100644 index 00000000000..c323b7a6731 --- /dev/null +++ b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + src\proto\grpc\testing + + + src\proto\grpc\testing + + + test\cpp\server + + + + + + {828e0ffc-a89a-de93-ae06-706d522188a1} + + + {538db689-e85f-c369-7020-8d78e0ee5049} + + + {351168ef-9b4f-6165-ff4f-0e13781910db} + + + {530a1a67-0a37-50f8-42d0-7ccf0ec34cfc} + + + {67afe178-6a18-fd24-bbe6-656fee5a5f10} + + + {aaa8777b-1bc3-abaa-5e6d-28040c5aa213} + + + {af770080-f515-c773-3ae0-243d5929bbd0} + + + + diff --git a/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj new file mode 100644 index 00000000000..09279e325da --- /dev/null +++ b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj @@ -0,0 +1,199 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D5A20C05-D9B2-970B-8429-94BC3F58D1C4} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + stream_owned_slice_test + static + Debug + static + Debug + + + stream_owned_slice_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj.filters b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj.filters new file mode 100644 index 00000000000..9a412021972 --- /dev/null +++ b/vsprojects/vcxproj/test/stream_owned_slice_test/stream_owned_slice_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\core\transport + + + + + + {5606d0c3-ce6d-0d92-aaa6-4cba3360af30} + + + {c89700dc-cc90-bd03-00e7-36ee75d20c07} + + + {faebe48f-9338-a5a4-439d-9f307d0b843b} + + + +