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

pull/16697/head
Mark D. Roth 6 years ago
commit 9e0c210f7c
  1. 36
      CMakeLists.txt
  2. 66
      Makefile
  3. 6
      build.yaml
  4. 36
      src/core/ext/filters/client_channel/client_channel.cc
  5. 3
      src/core/ext/filters/client_channel/client_channel.h
  6. 1
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  7. 60
      src/core/ext/filters/client_channel/subchannel.cc
  8. 5
      src/core/ext/filters/http/client_authority_filter.cc
  9. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  10. 4
      src/core/lib/channel/channelz.h
  11. 7
      src/core/lib/iomgr/wakeup_fd_eventfd.cc
  12. 3
      src/core/lib/security/credentials/plugin/plugin_credentials.cc
  13. 14
      src/core/lib/surface/channel.cc
  14. 4
      src/core/lib/surface/channel.h
  15. 5
      src/core/lib/transport/metadata.cc
  16. 5
      src/core/lib/transport/metadata.h
  17. 40
      src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
  18. 2
      src/python/grpcio_tests/commands.py
  19. 22
      test/core/channel/channelz_test.cc
  20. 2
      test/core/compression/BUILD
  21. 32
      test/core/end2end/tests/channelz.cc
  22. 13
      test/core/end2end/tests/simple_request.cc
  23. 7
      test/cpp/util/config_grpc_cli.h
  24. 67
      test/cpp/util/grpc_tool.cc
  25. 397
      test/cpp/util/grpc_tool_test.cc
  26. 67
      test/cpp/util/proto_file_parser.cc
  27. 52
      test/cpp/util/proto_file_parser.h
  28. 25
      tools/internal_ci/linux/grpc_e2e_performance_singlevm.cfg
  29. 28
      tools/internal_ci/linux/grpc_e2e_performance_singlevm.sh
  30. 6
      tools/run_tests/generated/sources_and_headers.json
  31. 6
      tools/run_tests/generated/tests.json
  32. 15
      tools/run_tests/run_tests.py

@ -328,10 +328,10 @@ add_dependencies(buildtests_c grpc_jwt_verifier_test)
add_dependencies(buildtests_c grpc_security_connector_test)
add_dependencies(buildtests_c grpc_ssl_credentials_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c handshake_client)
add_dependencies(buildtests_c handshake_client_ssl)
endif()
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c handshake_server)
add_dependencies(buildtests_c handshake_server_ssl)
endif()
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c handshake_server_with_readahead_handshaker)
@ -362,7 +362,7 @@ add_dependencies(buildtests_c load_file_test)
add_dependencies(buildtests_c memory_profile_client)
add_dependencies(buildtests_c memory_profile_server)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c memory_profile_test)
add_dependencies(buildtests_c memory_usage_test)
endif()
add_dependencies(buildtests_c message_compress_test)
add_dependencies(buildtests_c minimal_stack_is_minimal_test)
@ -8041,12 +8041,12 @@ target_link_libraries(grpc_verify_jwt
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(handshake_client
add_executable(handshake_client_ssl
test/core/handshake/client_ssl.cc
)
target_include_directories(handshake_client
target_include_directories(handshake_client_ssl
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8059,7 +8059,7 @@ target_include_directories(handshake_client
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(handshake_client
target_link_libraries(handshake_client_ssl
${_gRPC_SSL_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
@ -8070,8 +8070,8 @@ target_link_libraries(handshake_client
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(handshake_client PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_client PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(handshake_client_ssl PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_client_ssl PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()
@ -8079,13 +8079,13 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(handshake_server
add_executable(handshake_server_ssl
test/core/handshake/server_ssl.cc
test/core/handshake/server_ssl_common.cc
)
target_include_directories(handshake_server
target_include_directories(handshake_server_ssl
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8098,7 +8098,7 @@ target_include_directories(handshake_server
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(handshake_server
target_link_libraries(handshake_server_ssl
${_gRPC_SSL_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
@ -8109,8 +8109,8 @@ target_link_libraries(handshake_server
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(handshake_server PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_server PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(handshake_server_ssl PROPERTIES LINKER_LANGUAGE C)
target_compile_options(handshake_server_ssl PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()
@ -8827,12 +8827,12 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(memory_profile_test
add_executable(memory_usage_test
test/core/memory_usage/memory_usage_test.cc
)
target_include_directories(memory_profile_test
target_include_directories(memory_usage_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -8845,7 +8845,7 @@ target_include_directories(memory_profile_test
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(memory_profile_test
target_link_libraries(memory_usage_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
@ -8855,8 +8855,8 @@ target_link_libraries(memory_profile_test
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(memory_profile_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_profile_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(memory_usage_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(memory_usage_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()

@ -1039,8 +1039,8 @@ grpc_print_google_default_creds_token: $(BINDIR)/$(CONFIG)/grpc_print_google_def
grpc_security_connector_test: $(BINDIR)/$(CONFIG)/grpc_security_connector_test
grpc_ssl_credentials_test: $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test
grpc_verify_jwt: $(BINDIR)/$(CONFIG)/grpc_verify_jwt
handshake_client: $(BINDIR)/$(CONFIG)/handshake_client
handshake_server: $(BINDIR)/$(CONFIG)/handshake_server
handshake_client_ssl: $(BINDIR)/$(CONFIG)/handshake_client_ssl
handshake_server_ssl: $(BINDIR)/$(CONFIG)/handshake_server_ssl
handshake_server_with_readahead_handshaker: $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker
handshake_verify_peer_options: $(BINDIR)/$(CONFIG)/handshake_verify_peer_options
histogram_test: $(BINDIR)/$(CONFIG)/histogram_test
@ -1066,7 +1066,7 @@ load_file_test: $(BINDIR)/$(CONFIG)/load_file_test
low_level_ping_pong_benchmark: $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
memory_profile_client: $(BINDIR)/$(CONFIG)/memory_profile_client
memory_profile_server: $(BINDIR)/$(CONFIG)/memory_profile_server
memory_profile_test: $(BINDIR)/$(CONFIG)/memory_profile_test
memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test
message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test
multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test
@ -1491,8 +1491,8 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test \
$(BINDIR)/$(CONFIG)/grpc_security_connector_test \
$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test \
$(BINDIR)/$(CONFIG)/handshake_client \
$(BINDIR)/$(CONFIG)/handshake_server \
$(BINDIR)/$(CONFIG)/handshake_client_ssl \
$(BINDIR)/$(CONFIG)/handshake_server_ssl \
$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker \
$(BINDIR)/$(CONFIG)/handshake_verify_peer_options \
$(BINDIR)/$(CONFIG)/histogram_test \
@ -1513,7 +1513,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/load_file_test \
$(BINDIR)/$(CONFIG)/memory_profile_client \
$(BINDIR)/$(CONFIG)/memory_profile_server \
$(BINDIR)/$(CONFIG)/memory_profile_test \
$(BINDIR)/$(CONFIG)/memory_usage_test \
$(BINDIR)/$(CONFIG)/message_compress_test \
$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \
$(BINDIR)/$(CONFIG)/multiple_server_queues_test \
@ -2058,10 +2058,10 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/grpc_security_connector_test || ( echo test grpc_security_connector_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_ssl_credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test || ( echo test grpc_ssl_credentials_test failed ; exit 1 )
$(E) "[RUN] Testing handshake_client"
$(Q) $(BINDIR)/$(CONFIG)/handshake_client || ( echo test handshake_client failed ; exit 1 )
$(E) "[RUN] Testing handshake_server"
$(Q) $(BINDIR)/$(CONFIG)/handshake_server || ( echo test handshake_server failed ; exit 1 )
$(E) "[RUN] Testing handshake_client_ssl"
$(Q) $(BINDIR)/$(CONFIG)/handshake_client_ssl || ( echo test handshake_client_ssl failed ; exit 1 )
$(E) "[RUN] Testing handshake_server_ssl"
$(Q) $(BINDIR)/$(CONFIG)/handshake_server_ssl || ( echo test handshake_server_ssl failed ; exit 1 )
$(E) "[RUN] Testing handshake_server_with_readahead_handshaker"
$(Q) $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker || ( echo test handshake_server_with_readahead_handshaker failed ; exit 1 )
$(E) "[RUN] Testing handshake_verify_peer_options"
@ -2096,8 +2096,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/lame_client_test || ( echo test lame_client_test failed ; exit 1 )
$(E) "[RUN] Testing load_file_test"
$(Q) $(BINDIR)/$(CONFIG)/load_file_test || ( echo test load_file_test failed ; exit 1 )
$(E) "[RUN] Testing memory_profile_test"
$(Q) $(BINDIR)/$(CONFIG)/memory_profile_test || ( echo test memory_profile_test failed ; exit 1 )
$(E) "[RUN] Testing memory_usage_test"
$(Q) $(BINDIR)/$(CONFIG)/memory_usage_test || ( echo test memory_usage_test failed ; exit 1 )
$(E) "[RUN] Testing message_compress_test"
$(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 )
$(E) "[RUN] Testing minimal_stack_is_minimal_test"
@ -12670,57 +12670,57 @@ endif
endif
HANDSHAKE_CLIENT_SRC = \
HANDSHAKE_CLIENT_SSL_SRC = \
test/core/handshake/client_ssl.cc \
HANDSHAKE_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_CLIENT_SRC))))
HANDSHAKE_CLIENT_SSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_CLIENT_SSL_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/handshake_client: openssl_dep_error
$(BINDIR)/$(CONFIG)/handshake_client_ssl: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/handshake_client: $(HANDSHAKE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl
endif
$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_handshake_client: $(HANDSHAKE_CLIENT_OBJS:.o=.dep)
deps_handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(HANDSHAKE_CLIENT_OBJS:.o=.dep)
-include $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep)
endif
endif
HANDSHAKE_SERVER_SRC = \
HANDSHAKE_SERVER_SSL_SRC = \
test/core/handshake/server_ssl.cc \
test/core/handshake/server_ssl_common.cc \
HANDSHAKE_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_SERVER_SRC))))
HANDSHAKE_SERVER_SSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_SERVER_SSL_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/handshake_server: openssl_dep_error
$(BINDIR)/$(CONFIG)/handshake_server_ssl: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/handshake_server: $(HANDSHAKE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server
$(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl
endif
@ -12728,11 +12728,11 @@ $(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgr
$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_handshake_server: $(HANDSHAKE_SERVER_OBJS:.o=.dep)
deps_handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(HANDSHAKE_SERVER_OBJS:.o=.dep)
-include $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep)
endif
endif
@ -13540,34 +13540,34 @@ endif
endif
MEMORY_PROFILE_TEST_SRC = \
MEMORY_USAGE_TEST_SRC = \
test/core/memory_usage/memory_usage_test.cc \
MEMORY_PROFILE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_TEST_SRC))))
MEMORY_USAGE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_USAGE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/memory_profile_test: openssl_dep_error
$(BINDIR)/$(CONFIG)/memory_usage_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/memory_profile_test: $(MEMORY_PROFILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_test
$(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test
endif
$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_memory_profile_test: $(MEMORY_PROFILE_TEST_OBJS:.o=.dep)
deps_memory_usage_test: $(MEMORY_USAGE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(MEMORY_PROFILE_TEST_OBJS:.o=.dep)
-include $(MEMORY_USAGE_TEST_OBJS:.o=.dep)
endif
endif

@ -2786,7 +2786,7 @@ targets:
filegroups:
- cmdline
uses_polling: false
- name: handshake_client
- name: handshake_client_ssl
build: test
language: c
src:
@ -2801,7 +2801,7 @@ targets:
platforms:
- linux
secure: true
- name: handshake_server
- name: handshake_server_ssl
build: test
language: c
headers:
@ -3123,7 +3123,7 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: memory_profile_test
- name: memory_usage_test
cpu_cost: 1.5
build: test
language: c

@ -129,6 +129,8 @@ typedef struct client_channel_channel_data {
grpc_core::UniquePtr<char> info_lb_policy_name;
/** service config in JSON form */
grpc_core::UniquePtr<char> info_service_config_json;
/* backpointer to grpc_channel's channelz node */
grpc_core::channelz::ClientChannelNode* channelz_channel;
} channel_data;
typedef struct {
@ -153,6 +155,23 @@ static void watch_lb_policy_locked(channel_data* chand,
grpc_core::LoadBalancingPolicy* lb_policy,
grpc_connectivity_state current_state);
static const char* channel_connectivity_state_change_string(
grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_IDLE:
return "Channel state change to IDLE";
case GRPC_CHANNEL_CONNECTING:
return "Channel state change to CONNECTING";
case GRPC_CHANNEL_READY:
return "Channel state change to READY";
case GRPC_CHANNEL_TRANSIENT_FAILURE:
return "Channel state change to TRANSIENT_FAILURE";
case GRPC_CHANNEL_SHUTDOWN:
return "Channel state change to SHUTDOWN";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_channel_connectivity_state_locked(channel_data* chand,
grpc_connectivity_state state,
grpc_error* error,
@ -177,6 +196,12 @@ static void set_channel_connectivity_state_locked(channel_data* chand,
gpr_log(GPR_INFO, "chand=%p: setting connectivity state to %s", chand,
grpc_connectivity_state_name(state));
}
if (chand->channelz_channel != nullptr) {
chand->channelz_channel->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
channel_connectivity_state_change_string(state)));
}
grpc_connectivity_state_set(&chand->state_tracker, state, error, reason);
}
@ -699,6 +724,7 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem,
// Record enable_retries.
arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES);
chand->enable_retries = grpc_channel_arg_get_bool(arg, true);
chand->channelz_channel = nullptr;
// Record client channel factory.
arg = grpc_channel_args_find(args->channel_args,
GRPC_ARG_CLIENT_CHANNEL_FACTORY);
@ -2194,9 +2220,9 @@ static void add_retriable_send_initial_metadata_op(
.grpc_previous_rpc_attempts);
}
if (GPR_UNLIKELY(calld->num_attempts_completed > 0)) {
grpc_mdelem retry_md = grpc_mdelem_from_slices(
grpc_mdelem retry_md = grpc_mdelem_create(
GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS,
*retry_count_strings[calld->num_attempts_completed - 1]);
*retry_count_strings[calld->num_attempts_completed - 1], nullptr);
grpc_error* error = grpc_metadata_batch_add_tail(
&retry_state->send_initial_metadata,
&retry_state->send_initial_metadata_storage[calld->send_initial_metadata
@ -3208,6 +3234,12 @@ static void try_to_connect_locked(void* arg, grpc_error* error_ignored) {
GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect");
}
void grpc_client_channel_set_channelz_node(
grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
chand->channelz_channel = node;
}
void grpc_client_channel_populate_child_refs(
grpc_channel_element* elem,
grpc_core::channelz::ChildRefsList* child_subchannels,

@ -40,6 +40,9 @@ extern grpc_core::TraceFlag grpc_client_channel_trace;
extern const grpc_channel_filter grpc_client_channel_filter;
void grpc_client_channel_set_channelz_node(
grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node);
void grpc_client_channel_populate_child_refs(
grpc_channel_element* elem,
grpc_core::channelz::ChildRefsList* child_subchannels,

@ -49,6 +49,7 @@ ClientChannelNode::ClientChannelNode(grpc_channel* channel,
: ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) {
client_channel_ =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
grpc_client_channel_set_channelz_node(client_channel_, this);
GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter);
}

@ -428,6 +428,35 @@ intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) {
}
}
static const char* subchannel_connectivity_state_change_string(
grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_IDLE:
return "Subchannel state change to IDLE";
case GRPC_CHANNEL_CONNECTING:
return "Subchannel state change to CONNECTING";
case GRPC_CHANNEL_READY:
return "Subchannel state change to READY";
case GRPC_CHANNEL_TRANSIENT_FAILURE:
return "Subchannel state change to TRANSIENT_FAILURE";
case GRPC_CHANNEL_SHUTDOWN:
return "Subchannel state change to SHUTDOWN";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_subchannel_connectivity_state_locked(
grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error,
const char* reason) {
if (c->channelz_subchannel != nullptr) {
c->channelz_subchannel->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
subchannel_connectivity_state_change_string(state)));
}
grpc_connectivity_state_set(&c->state_tracker, state, error, reason);
}
static void continue_connect_locked(grpc_subchannel* c) {
grpc_connect_in_args args;
args.interested_parties = c->pollset_set;
@ -436,8 +465,8 @@ static void continue_connect_locked(grpc_subchannel* c) {
c->next_attempt_deadline = c->backoff->NextAttemptTime();
args.deadline = std::max(c->next_attempt_deadline, min_deadline);
args.channel_args = c->args;
grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "connecting");
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "connecting");
grpc_connector_connect(c->connector, &args, &c->connecting_result,
&c->on_connected);
}
@ -587,9 +616,9 @@ static void on_connected_subchannel_connectivity_changed(void* p,
connected_subchannel_watcher->connectivity_state));
}
c->connected_subchannel.reset();
grpc_connectivity_state_set(&c->state_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "reflect_child");
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
"reflect_child");
c->backoff_begun = false;
c->backoff->Reset();
maybe_start_connecting_locked(c);
@ -600,8 +629,8 @@ static void on_connected_subchannel_connectivity_changed(void* p,
break;
}
default: {
grpc_connectivity_state_set(
&c->state_tracker, connected_subchannel_watcher->connectivity_state,
set_subchannel_connectivity_state_locked(
c, connected_subchannel_watcher->connectivity_state,
GRPC_ERROR_REF(error), "reflect_child");
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
c->connected_subchannel->NotifyOnStateChange(
@ -672,8 +701,8 @@ static bool publish_transport_locked(grpc_subchannel* c) {
&connected_subchannel_watcher->closure);
/* signal completion */
grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connected");
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connected");
return true;
}
@ -690,8 +719,8 @@ static void on_subchannel_connected(void* arg, grpc_error* error) {
} else if (c->disconnected) {
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
} else {
grpc_connectivity_state_set(
&c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_TRANSIENT_FAILURE,
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Connect Failed", &error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
@ -760,9 +789,12 @@ static void get_call_status(grpc_subchannel_call* call,
grpc_error_get_status(error, call->deadline, status, nullptr, nullptr,
nullptr);
} else {
GPR_ASSERT(md_batch->idx.named.grpc_status != nullptr);
*status =
grpc_get_status_code_from_metadata(md_batch->idx.named.grpc_status->md);
if (md_batch->idx.named.grpc_status != nullptr) {
*status = grpc_get_status_code_from_metadata(
md_batch->idx.named.grpc_status->md);
} else {
*status = GRPC_STATUS_UNKNOWN;
}
}
GRPC_ERROR_UNREF(error);
}

@ -59,9 +59,8 @@ void authority_start_transport_stream_op_batch(
initial_metadata->idx.named.authority == nullptr) {
grpc_error* error = grpc_metadata_batch_add_head(
initial_metadata, &calld->authority_storage,
grpc_mdelem_from_slices(
GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(chand->default_authority)));
grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, chand->default_authority,
nullptr));
if (error != GRPC_ERROR_NONE) {
grpc_transport_stream_op_batch_finish_with_failure(batch, error,
calld->call_combiner);

@ -2128,8 +2128,7 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
"add_status_message",
grpc_chttp2_incoming_metadata_buffer_replace_or_add(
&s->metadata_buffer[1],
grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_MESSAGE,
grpc_slice_ref_internal(slice))));
grpc_mdelem_create(GRPC_MDSTR_GRPC_MESSAGE, slice, nullptr)));
}
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s);

@ -42,13 +42,13 @@
/** This is the default value for whether or not to enable channelz. If
* GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */
#define GRPC_ENABLE_CHANNELZ_DEFAULT false
#define GRPC_ENABLE_CHANNELZ_DEFAULT true
/** This is the default value for the maximum amount of memory used by trace
* events per channel trace node. If
* GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE is set, it will override
* this default value. */
#define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT 0
#define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT 1024 * 4
namespace grpc_core {

@ -32,12 +32,11 @@
#include "src/core/lib/profiling/timers.h"
static grpc_error* eventfd_create(grpc_wakeup_fd* fd_info) {
int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (efd < 0) {
fd_info->read_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
fd_info->write_fd = -1;
if (fd_info->read_fd < 0) {
return GRPC_OS_ERROR(errno, "eventfd");
}
fd_info->read_fd = efd;
fd_info->write_fd = -1;
return GRPC_ERROR_NONE;
}

@ -102,8 +102,7 @@ static grpc_error* process_plugin_result(
} else {
for (size_t i = 0; i < num_md; ++i) {
grpc_mdelem mdelem =
grpc_mdelem_from_slices(grpc_slice_ref_internal(md[i].key),
grpc_slice_ref_internal(md[i].value));
grpc_mdelem_create(md[i].key, md[i].value, nullptr);
grpc_credentials_mdelem_array_add(r->md_array, mdelem);
GRPC_MDELEM_UNREF(mdelem);
}

@ -336,9 +336,8 @@ grpc_call* grpc_channel_create_call(grpc_channel* channel,
grpc_core::ExecCtx exec_ctx;
grpc_call* call = grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, cq, nullptr,
grpc_mdelem_from_slices(GRPC_MDSTR_PATH, grpc_slice_ref_internal(method)),
host != nullptr ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(*host))
grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
: GRPC_MDNULL,
grpc_timespec_to_millis_round_up(deadline));
@ -347,14 +346,13 @@ grpc_call* grpc_channel_create_call(grpc_channel* channel,
grpc_call* grpc_channel_create_pollset_set_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
grpc_pollset_set* pollset_set, grpc_slice method, const grpc_slice* host,
grpc_millis deadline, void* reserved) {
grpc_pollset_set* pollset_set, const grpc_slice& method,
const grpc_slice* host, grpc_millis deadline, void* reserved) {
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, nullptr, pollset_set,
grpc_mdelem_from_slices(GRPC_MDSTR_PATH, grpc_slice_ref_internal(method)),
host != nullptr ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(*host))
grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
: GRPC_MDNULL,
deadline);
}

@ -45,8 +45,8 @@ grpc_channel* grpc_channel_create_with_builder(
value of \a propagation_mask (see propagation_bits.h for possible values) */
grpc_call* grpc_channel_create_pollset_set_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
grpc_pollset_set* pollset_set, grpc_slice method, const grpc_slice* host,
grpc_millis deadline, void* reserved);
grpc_pollset_set* pollset_set, const grpc_slice& method,
const grpc_slice* host, grpc_millis deadline, void* reserved);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack* grpc_channel_get_channel_stack(grpc_channel* channel);

@ -237,7 +237,7 @@ static void rehash_mdtab(mdtab_shard* shard) {
}
grpc_mdelem grpc_mdelem_create(
grpc_slice key, grpc_slice value,
const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store) {
if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) {
if (compatible_external_backing_store != nullptr) {
@ -324,7 +324,8 @@ grpc_mdelem grpc_mdelem_create(
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
}
grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) {
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
const grpc_slice& value) {
grpc_mdelem out = grpc_mdelem_create(key, value, nullptr);
grpc_slice_unref_internal(key);
grpc_slice_unref_internal(value);

@ -109,7 +109,8 @@ struct grpc_mdelem {
(uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
/* Unrefs the slices. */
grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value);
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
const grpc_slice& value);
/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
object as backing storage (so lifetimes should align) */
@ -120,7 +121,7 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata);
compatible_external_backing_store if it is non-NULL (in which case it's the
users responsibility to ensure that it outlives usage) */
grpc_mdelem grpc_mdelem_create(
grpc_slice key, grpc_slice value,
const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store);
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);

@ -51,11 +51,12 @@ namespace Grpc.Core.Internal
Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath);
this.handle = PlatformSpecificLoadLibrary(this.libraryPath);
this.handle = PlatformSpecificLoadLibrary(this.libraryPath, out string loadLibraryErrorDetail);
if (this.handle == IntPtr.Zero)
{
throw new IOException(string.Format("Error loading native library \"{0}\"", this.libraryPath));
throw new IOException(string.Format("Error loading native library \"{0}\". {1}",
this.libraryPath, loadLibraryErrorDetail));
}
}
@ -129,31 +130,44 @@ namespace Grpc.Core.Internal
/// <summary>
/// Loads library in a platform specific way.
/// </summary>
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath)
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath, out string errorMsg)
{
if (PlatformApis.IsWindows)
{
// TODO(jtattermusch): populate the error on Windows
errorMsg = null;
return Windows.LoadLibrary(libraryPath);
}
if (PlatformApis.IsLinux)
{
if (PlatformApis.IsMono)
{
return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(Mono.dlopen, Mono.dlerror, libraryPath, out errorMsg);
}
if (PlatformApis.IsNetCore)
{
return CoreCLR.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(CoreCLR.dlopen, CoreCLR.dlerror, libraryPath, out errorMsg);
}
return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(Linux.dlopen, Linux.dlerror, libraryPath, out errorMsg);
}
if (PlatformApis.IsMacOSX)
{
return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
return LoadLibraryPosix(MacOSX.dlopen, MacOSX.dlerror, libraryPath, out errorMsg);
}
throw new InvalidOperationException("Unsupported platform.");
}
private static IntPtr LoadLibraryPosix(Func<string, int, IntPtr> dlopenFunc, Func<IntPtr> dlerrorFunc, string libraryPath, out string errorMsg)
{
errorMsg = null;
IntPtr ret = dlopenFunc(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
if (ret == IntPtr.Zero)
{
errorMsg = Marshal.PtrToStringAnsi(dlerrorFunc());
}
return ret;
}
private static string FirstValidLibraryPath(string[] libraryPathAlternatives)
{
GrpcPreconditions.CheckArgument(libraryPathAlternatives.Length > 0, "libraryPathAlternatives cannot be empty.");
@ -183,6 +197,9 @@ namespace Grpc.Core.Internal
[DllImport("libdl.so")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libdl.so")]
internal static extern IntPtr dlerror();
[DllImport("libdl.so")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
@ -192,6 +209,9 @@ namespace Grpc.Core.Internal
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlerror();
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
@ -208,6 +228,9 @@ namespace Grpc.Core.Internal
[DllImport("__Internal")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("__Internal")]
internal static extern IntPtr dlerror();
[DllImport("__Internal")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
@ -222,6 +245,9 @@ namespace Grpc.Core.Internal
[DllImport("libcoreclr.so")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libcoreclr.so")]
internal static extern IntPtr dlerror();
[DllImport("libcoreclr.so")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}

@ -116,6 +116,8 @@ class TestGevent(setuptools.Command):
# eventually succeed, but need to dig into performance issues.
'unit._cython._no_messages_server_completion_queue_per_call_test.Test.test_rpcs',
'unit._cython._no_messages_single_server_completion_queue_test.Test.test_rpcs',
# TODO(https://github.com/grpc/grpc/issues/16890) enable this test
'unit._cython._channel_test.ChannelTest.test_multiple_channels_lonely_connectivity',
# I have no idea why this doesn't work in gevent, but it shouldn't even be
# using the c-core
'testing._client_test.ClientTest.test_infinite_request_stream_real_time',

@ -126,12 +126,12 @@ void ValidateGetServers(size_t expected_servers) {
class ChannelFixture {
public:
ChannelFixture(int max_tracer_event_memory = 0) {
grpc_arg client_a[2];
client_a[0] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
max_tracer_event_memory);
client_a[1] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true);
grpc_arg client_a[] = {
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
max_tracer_event_memory),
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true)};
grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
channel_ =
grpc_insecure_channel_create("fake_target", &client_args, nullptr);
@ -238,8 +238,16 @@ TEST_P(ChannelzChannelTest, BasicChannel) {
TEST(ChannelzChannelTest, ChannelzDisabled) {
grpc_core::ExecCtx exec_ctx;
// explicitly disable channelz
grpc_arg arg[] = {
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
0),
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), false)};
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
grpc_channel* channel =
grpc_insecure_channel_create("fake_target", nullptr, nullptr);
grpc_insecure_channel_create("fake_target", &args, nullptr);
ChannelNode* channelz_channel = grpc_channel_get_channelz_node(channel);
ASSERT_EQ(channelz_channel, nullptr);
grpc_channel_destroy(channel);

@ -55,7 +55,7 @@ grpc_cc_test(
)
grpc_cc_test(
name = "stream_compress_test",
name = "stream_compression_test",
srcs = ["stream_compression_test.cc"],
language = "C++",
deps = [

@ -199,9 +199,13 @@ static void run_one_request(grpc_end2end_test_config config,
static void test_channelz(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
grpc_arg arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true);
grpc_channel_args args = {1, &arg};
grpc_arg arg[] = {
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
0),
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true)};
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
f = begin_test(config, "test_channelz", &args, &args);
grpc_core::channelz::ChannelNode* channelz_channel =
@ -267,12 +271,12 @@ static void test_channelz(grpc_end2end_test_config config) {
static void test_channelz_with_channel_trace(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
grpc_arg arg[2];
arg[0] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
1024 * 1024);
arg[1] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true);
grpc_arg arg[] = {
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
1024 * 1024),
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true)};
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
f = begin_test(config, "test_channelz_with_channel_trace", &args, &args);
@ -307,7 +311,15 @@ static void test_channelz_with_channel_trace(grpc_end2end_test_config config) {
static void test_channelz_disabled(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
f = begin_test(config, "test_channelz_disabled", nullptr, nullptr);
grpc_arg arg[] = {
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
0),
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), false)};
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
f = begin_test(config, "test_channelz_disabled", &args, &args);
grpc_core::channelz::ChannelNode* channelz_channel =
grpc_channel_get_channelz_node(f.client);
GPR_ASSERT(channelz_channel == nullptr);

@ -108,7 +108,9 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_stats_data* after =
static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data)));
#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
grpc_stats_collect(before);
#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
gpr_timespec deadline = five_seconds_from_now();
c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
@ -225,17 +227,18 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verifier_destroy(cqv);
int expected_calls = 1;
if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
expected_calls *= 2;
}
#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
grpc_stats_collect(after);
char* stats = grpc_stats_data_as_json(after);
gpr_log(GPR_DEBUG, "%s", stats);
gpr_free(stats);
int expected_calls = 1;
if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
expected_calls *= 2;
}
#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] -
before->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] ==
expected_calls);

@ -40,6 +40,11 @@
#define GRPC_CUSTOM_TEXTFORMAT ::google::protobuf::TextFormat
#endif
#ifndef GRPC_CUSTOM_JSONUTIL
#include <google/protobuf/util/json_util.h>
#define GRPC_CUSTOM_JSONUTIL ::google::protobuf::util
#endif
#ifndef GRPC_CUSTOM_DISKSOURCETREE
#include <google/protobuf/compiler/importer.h>
#define GRPC_CUSTOM_DISKSOURCETREE ::google::protobuf::compiler::DiskSourceTree
@ -58,6 +63,8 @@ typedef GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase;
typedef GRPC_CUSTOM_TEXTFORMAT TextFormat;
namespace json = GRPC_CUSTOM_JSONUTIL;
namespace compiler {
typedef GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree;
typedef GRPC_CUSTOM_IMPORTER Importer;

@ -57,6 +57,8 @@ DEFINE_string(proto_path, ".", "Path to look for the proto file.");
DEFINE_string(protofiles, "", "Name of the proto file.");
DEFINE_bool(binary_input, false, "Input in binary format");
DEFINE_bool(binary_output, false, "Output in binary format");
DEFINE_bool(json_input, false, "Input in json format");
DEFINE_bool(json_output, false, "Output in json format");
DEFINE_string(infile, "", "Input file (default is stdin)");
DEFINE_bool(batch, false,
"Input contains multiple requests. Please do not use this to send "
@ -88,6 +90,8 @@ class GrpcTool {
GrpcToolOutputCallback callback);
bool ToText(int argc, const char** argv, const CliCredentials& cred,
GrpcToolOutputCallback callback);
bool ToJson(int argc, const char** argv, const CliCredentials& cred,
GrpcToolOutputCallback callback);
bool ToBinary(int argc, const char** argv, const CliCredentials& cred,
GrpcToolOutputCallback callback);
@ -189,8 +193,9 @@ void ReadResponse(CliCall* call, const grpc::string& method_name,
fprintf(stderr, "got response.\n");
if (!FLAGS_binary_output) {
gpr_mu_lock(parser_mu);
serialized_response_proto = parser->GetTextFormatFromMethod(
method_name, serialized_response_proto, false /* is_request */);
serialized_response_proto = parser->GetFormattedStringFromMethod(
method_name, serialized_response_proto, false /* is_request */,
FLAGS_json_output);
if (parser->HasError() && print_mode) {
fprintf(stderr, "Failed to parse response.\n");
}
@ -233,6 +238,7 @@ const Command ops[] = {
{"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3},
{"totext", BindWith5Args(&GrpcTool::ToText), 2, 3},
{"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3},
{"tojson", BindWith5Args(&GrpcTool::ToJson), 2, 3},
};
void Usage(const grpc::string& msg) {
@ -244,6 +250,7 @@ void Usage(const grpc::string& msg) {
" grpc_cli type ... ; Print type\n"
" grpc_cli parse ... ; Parse message\n"
" grpc_cli totext ... ; Convert binary message to text\n"
" grpc_cli tojson ... ; Convert binary message to json\n"
" grpc_cli tobinary ... ; Convert text message to binary\n"
" grpc_cli help ... ; Print this message, or per-command usage\n"
"\n",
@ -465,7 +472,9 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
" --infile ; Input filename (defaults to stdin)\n"
" --outfile ; Output filename (defaults to stdout)\n"
" --binary_input ; Input in binary format\n"
" --binary_output ; Output in binary format\n" +
" --binary_output ; Output in binary format\n"
" --json_input ; Input in json format\n"
" --json_output ; Output in json format\n" +
cred.GetCredentialUsage());
std::stringstream output_ss;
@ -548,7 +557,8 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
} else {
gpr_mu_lock(&parser_mu);
serialized_request_proto = parser->GetSerializedProtoFromMethod(
method_name, request_text, true /* is_request */);
method_name, request_text, true /* is_request */,
FLAGS_json_input);
request_text.clear();
if (parser->HasError()) {
if (print_mode) {
@ -632,7 +642,8 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
request_text.clear();
} else {
serialized_request_proto = parser->GetSerializedProtoFromMethod(
method_name, request_text, true /* is_request */);
method_name, request_text, true /* is_request */,
FLAGS_json_input);
request_text.clear();
if (parser->HasError()) {
if (print_mode) {
@ -668,9 +679,10 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
break;
}
} else {
grpc::string response_text = parser->GetTextFormatFromMethod(
grpc::string response_text = parser->GetFormattedStringFromMethod(
method_name, serialized_response_proto,
false /* is_request */);
false /* is_request */, FLAGS_json_output);
if (parser->HasError() && print_mode) {
fprintf(stderr, "Failed to parse response.\n");
} else {
@ -727,7 +739,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
serialized_request_proto = request_text;
} else {
serialized_request_proto = parser->GetSerializedProtoFromMethod(
method_name, request_text, true /* is_request */);
method_name, request_text, true /* is_request */, FLAGS_json_input);
if (parser->HasError()) {
fprintf(stderr, "Failed to parse request.\n");
return false;
@ -751,13 +763,15 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
receive_initial_metadata ? &server_initial_metadata : nullptr);
receive_initial_metadata = false) {
if (!FLAGS_binary_output) {
serialized_response_proto = parser->GetTextFormatFromMethod(
method_name, serialized_response_proto, false /* is_request */);
serialized_response_proto = parser->GetFormattedStringFromMethod(
method_name, serialized_response_proto, false /* is_request */,
FLAGS_json_output);
if (parser->HasError()) {
fprintf(stderr, "Failed to parse response.\n");
return false;
}
}
if (receive_initial_metadata) {
PrintMetadata(server_initial_metadata,
"Received initial metadata from server:");
@ -797,7 +811,9 @@ bool GrpcTool::ParseMessage(int argc, const char** argv,
" --infile ; Input filename (defaults to stdin)\n"
" --outfile ; Output filename (defaults to stdout)\n"
" --binary_input ; Input in binary format\n"
" --binary_output ; Output in binary format\n" +
" --binary_output ; Output in binary format\n"
" --json_input ; Input in json format\n"
" --json_output ; Output in json format\n" +
cred.GetCredentialUsage());
std::stringstream output_ss;
@ -844,8 +860,8 @@ bool GrpcTool::ParseMessage(int argc, const char** argv,
if (FLAGS_binary_input) {
serialized_request_proto = message_text;
} else {
serialized_request_proto =
parser->GetSerializedProtoFromMessageType(type_name, message_text);
serialized_request_proto = parser->GetSerializedProtoFromMessageType(
type_name, message_text, FLAGS_json_input);
if (parser->HasError()) {
fprintf(stderr, "Failed to serialize the message.\n");
return false;
@ -855,12 +871,14 @@ bool GrpcTool::ParseMessage(int argc, const char** argv,
if (FLAGS_binary_output) {
output_ss << serialized_request_proto;
} else {
grpc::string output_text = parser->GetTextFormatFromMessageType(
type_name, serialized_request_proto);
grpc::string output_text;
output_text = parser->GetFormattedStringFromMessageType(
type_name, serialized_request_proto, FLAGS_json_output);
if (parser->HasError()) {
fprintf(stderr, "Failed to deserialize the message.\n");
return false;
}
output_ss << output_text << std::endl;
}
@ -885,6 +903,25 @@ bool GrpcTool::ToText(int argc, const char** argv, const CliCredentials& cred,
return ParseMessage(argc, argv, cred, callback);
}
bool GrpcTool::ToJson(int argc, const char** argv, const CliCredentials& cred,
GrpcToolOutputCallback callback) {
CommandUsage(
"Convert binary message to json\n"
" grpc_cli tojson <protofiles> <type>\n"
" <protofiles> ; Comma separated list of proto files\n"
" <type> ; Protocol buffer type name\n"
" --proto_path ; The search path of proto files\n"
" --infile ; Input filename (defaults to stdin)\n"
" --outfile ; Output filename (defaults to stdout)\n");
FLAGS_protofiles = argv[0];
FLAGS_remotedb = false;
FLAGS_binary_input = true;
FLAGS_binary_output = false;
FLAGS_json_output = true;
return ParseMessage(argc, argv, cred, callback);
}
bool GrpcTool::ToBinary(int argc, const char** argv, const CliCredentials& cred,
GrpcToolOutputCallback callback) {
CommandUsage(

@ -74,11 +74,20 @@ using grpc::testing::EchoResponse;
" rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
"{}\n"
#define ECHO_RESPONSE_MESSAGE \
"message: \"echo\"\n" \
"param {\n" \
" host: \"localhost\"\n" \
" peer: \"peer\"\n" \
#define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT \
"message: \"echo\"\n" \
"param {\n" \
" host: \"localhost\"\n" \
" peer: \"peer\"\n" \
"}\n\n"
#define ECHO_RESPONSE_MESSAGE_JSON_FORMAT \
"{\n" \
" \"message\": \"echo\",\n" \
" \"param\": {\n" \
" \"host\": \"localhost\",\n" \
" \"peer\": \"peer\"\n" \
" }\n" \
"}\n\n"
DECLARE_string(channel_creds_type);
@ -89,6 +98,8 @@ namespace testing {
DECLARE_bool(binary_input);
DECLARE_bool(binary_output);
DECLARE_bool(json_input);
DECLARE_bool(json_output);
DECLARE_bool(l);
DECLARE_bool(batch);
DECLARE_string(metadata);
@ -426,6 +437,61 @@ TEST_F(GrpcToolTest, CallCommand) {
// Expected output: "message: \"Hello\""
EXPECT_TRUE(nullptr !=
strstr(output_stream.str().c_str(), "message: \"Hello\""));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
// Expected output:
// {
// "message": "Hello"
// }
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"{\n \"message\": \"Hello\"\n}"));
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandJsonInput) {
// Test input "grpc_cli call localhost:<port> Echo "{ \"message\": \"Hello\"}"
std::stringstream output_stream;
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
"{ \"message\": \"Hello\"}"};
FLAGS_json_input = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
// Expected output: "message: \"Hello\""
EXPECT_TRUE(nullptr !=
strstr(output_stream.str().c_str(), "message: \"Hello\""));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
FLAGS_json_input = false;
// Expected output:
// {
// "message": "Hello"
// }
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"{\n \"message\": \"Hello\"\n}"));
ShutdownServer();
}
@ -453,6 +519,101 @@ TEST_F(GrpcToolTest, CallCommandBatch) {
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"message: \"Hello0\"\nmessage: "
"\"Hello1\"\nmessage: \"Hello2\"\n"));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
ss.clear();
ss.seekg(0);
std::cin.rdbuf(ss.rdbuf());
FLAGS_batch = true;
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
FLAGS_batch = false;
// Expected output:
// {
// "message": "Hello0"
// }
// {
// "message": "Hello1"
// }
// {
// "message": "Hello2"
// }
// Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
// "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"{\n \"message\": \"Hello0\"\n}\n"
"{\n \"message\": \"Hello1\"\n}\n"
"{\n \"message\": \"Hello2\"\n}\n"));
std::cin.rdbuf(orig);
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandBatchJsonInput) {
// Test input "grpc_cli call Echo"
std::stringstream output_stream;
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
"{\"message\": \"Hello0\"}"};
// Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
std::streambuf* orig = std::cin.rdbuf();
std::istringstream ss(
"{\"message\": \"Hello1\"}\n\n{\"message\": \"Hello2\" }\n\n");
std::cin.rdbuf(ss.rdbuf());
FLAGS_json_input = true;
FLAGS_batch = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_batch = false;
// Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
// "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"message: \"Hello0\"\nmessage: "
"\"Hello1\"\nmessage: \"Hello2\"\n"));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
ss.clear();
ss.seekg(0);
std::cin.rdbuf(ss.rdbuf());
FLAGS_batch = true;
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
FLAGS_batch = false;
FLAGS_json_input = false;
// Expected output:
// {
// "message": "Hello0"
// }
// {
// "message": "Hello1"
// }
// {
// "message": "Hello2"
// }
// Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
// "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"{\n \"message\": \"Hello0\"\n}\n"
"{\n \"message\": \"Hello1\"\n}\n"
"{\n \"message\": \"Hello2\"\n}\n"));
std::cin.rdbuf(orig);
ShutdownServer();
}
@ -479,6 +640,95 @@ TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) {
// Expected output: "message: "Hello0"\nmessage: "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"message: \"Hello0\"\nmessage: \"Hello2\"\n"));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
ss.clear();
ss.seekg(0);
std::cin.rdbuf(ss.rdbuf());
FLAGS_batch = true;
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
FLAGS_batch = false;
// Expected output:
// {
// "message": "Hello0"
// }
// {
// "message": "Hello2"
// }
// Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
// "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"{\n \"message\": \"Hello0\"\n}\n"
"{\n \"message\": \"Hello2\"\n}\n"));
std::cin.rdbuf(orig);
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) {
// Test input "grpc_cli call Echo"
std::stringstream output_stream;
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
"{ \"message\": \"Hello0\"}"};
// Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n"
std::streambuf* orig = std::cin.rdbuf();
std::istringstream ss(
"{ \"message\": 1 }\n\n { \"message\": \"Hello2\" }\n\n");
std::cin.rdbuf(ss.rdbuf());
FLAGS_batch = true;
FLAGS_json_input = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_input = false;
FLAGS_batch = false;
// Expected output: "message: "Hello0"\nmessage: "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"message: \"Hello0\"\nmessage: \"Hello2\"\n"));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
ss.clear();
ss.seekg(0);
std::cin.rdbuf(ss.rdbuf());
FLAGS_batch = true;
FLAGS_json_input = true;
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
FLAGS_json_input = false;
FLAGS_batch = false;
// Expected output:
// {
// "message": "Hello0"
// }
// {
// "message": "Hello2"
// }
// Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
// "Hello2"\n"
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"{\n \"message\": \"Hello0\"\n}\n"
"{\n \"message\": \"Hello2\"\n}\n"));
std::cin.rdbuf(orig);
ShutdownServer();
}
@ -508,6 +758,34 @@ TEST_F(GrpcToolTest, CallCommandRequestStream) {
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) {
// Test input: grpc_cli call localhost:<port> RequestStream "{ \"message\":
// \"Hello0\"}"
std::stringstream output_stream;
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
"RequestStream", "{ \"message\": \"Hello0\" }"};
// Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
std::streambuf* orig = std::cin.rdbuf();
std::istringstream ss(
"{ \"message\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n");
std::cin.rdbuf(ss.rdbuf());
FLAGS_json_input = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_input = false;
// Expected output: "message: \"Hello0Hello1Hello2\""
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
"message: \"Hello0Hello1Hello2\""));
std::cin.rdbuf(orig);
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) {
// Test input: grpc_cli call localhost:<port> RequestStream "message:
// 'Hello0'"
@ -533,6 +811,34 @@ TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) {
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequestJsonInput) {
// Test input: grpc_cli call localhost:<port> RequestStream "message:
// 'Hello0'"
std::stringstream output_stream;
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
"RequestStream", "{ \"message\": \"Hello0\" }"};
// Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"
std::streambuf* orig = std::cin.rdbuf();
std::istringstream ss(
"{ \"bad_field\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n");
std::cin.rdbuf(ss.rdbuf());
FLAGS_json_input = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_input = false;
// Expected output: "message: \"Hello0Hello2\""
EXPECT_TRUE(nullptr !=
strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\""));
std::cin.rdbuf(orig);
ShutdownServer();
}
TEST_F(GrpcToolTest, CallCommandResponseStream) {
// Test input: grpc_cli call localhost:<port> ResponseStream "message:
// 'Hello'"
@ -554,6 +860,24 @@ TEST_F(GrpcToolTest, CallCommandResponseStream) {
expected_response_text.c_str()));
}
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
// Expected output: "{\n \"message\": \"Hello{n}\"\n}\n"
for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
grpc::string expected_response_text =
"{\n \"message\": \"Hello" + grpc::to_string(i) + "\"\n}\n";
EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
expected_response_text.c_str()));
}
ShutdownServer();
}
@ -617,15 +941,31 @@ TEST_F(GrpcToolTest, ParseCommand) {
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
"grpc.testing.EchoResponse", ECHO_RESPONSE_MESSAGE};
"grpc.testing.EchoResponse",
ECHO_RESPONSE_MESSAGE_TEXT_FORMAT};
FLAGS_binary_input = false;
FLAGS_binary_output = false;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
// Expected output: ECHO_RESPONSE_MESSAGE
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE));
// Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
ECHO_RESPONSE_MESSAGE_TEXT_FORMAT));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
// Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
ECHO_RESPONSE_MESSAGE_JSON_FORMAT));
// Parse text message to binary message and then parse it back to text message
output_stream.str(grpc::string());
@ -645,13 +985,52 @@ TEST_F(GrpcToolTest, ParseCommand) {
std::placeholders::_1)));
// Expected output: ECHO_RESPONSE_MESSAGE
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE));
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
ECHO_RESPONSE_MESSAGE_TEXT_FORMAT));
FLAGS_binary_input = false;
FLAGS_binary_output = false;
ShutdownServer();
}
TEST_F(GrpcToolTest, ParseCommandJsonFormat) {
// Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse
// ECHO_RESPONSE_MESSAGE_JSON_FORMAT"
std::stringstream output_stream;
std::stringstream binary_output_stream;
const grpc::string server_address = SetUpServer();
const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
"grpc.testing.EchoResponse",
ECHO_RESPONSE_MESSAGE_JSON_FORMAT};
FLAGS_json_input = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
// Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
ECHO_RESPONSE_MESSAGE_TEXT_FORMAT));
// with json_output
output_stream.str(grpc::string());
output_stream.clear();
FLAGS_json_output = true;
EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
std::bind(PrintStream, &output_stream,
std::placeholders::_1)));
FLAGS_json_output = false;
FLAGS_json_input = false;
// Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT
EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
ECHO_RESPONSE_MESSAGE_JSON_FORMAT));
ShutdownServer();
}
TEST_F(GrpcToolTest, TooFewArguments) {
// Test input "grpc_cli call Echo"
std::stringstream output_stream;

@ -217,31 +217,32 @@ bool ProtoFileParser::IsStreaming(const grpc::string& method, bool is_request) {
}
grpc::string ProtoFileParser::GetSerializedProtoFromMethod(
const grpc::string& method, const grpc::string& text_format_proto,
bool is_request) {
const grpc::string& method, const grpc::string& formatted_proto,
bool is_request, bool is_json_format) {
has_error_ = false;
grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request);
if (has_error_) {
return "";
}
return GetSerializedProtoFromMessageType(message_type_name,
text_format_proto);
return GetSerializedProtoFromMessageType(message_type_name, formatted_proto,
is_json_format);
}
grpc::string ProtoFileParser::GetTextFormatFromMethod(
grpc::string ProtoFileParser::GetFormattedStringFromMethod(
const grpc::string& method, const grpc::string& serialized_proto,
bool is_request) {
bool is_request, bool is_json_format) {
has_error_ = false;
grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request);
if (has_error_) {
return "";
}
return GetTextFormatFromMessageType(message_type_name, serialized_proto);
return GetFormattedStringFromMessageType(message_type_name, serialized_proto,
is_json_format);
}
grpc::string ProtoFileParser::GetSerializedProtoFromMessageType(
const grpc::string& message_type_name,
const grpc::string& text_format_proto) {
const grpc::string& message_type_name, const grpc::string& formatted_proto,
bool is_json_format) {
has_error_ = false;
grpc::string serialized;
const protobuf::Descriptor* desc =
@ -252,11 +253,23 @@ grpc::string ProtoFileParser::GetSerializedProtoFromMessageType(
}
std::unique_ptr<grpc::protobuf::Message> msg(
dynamic_factory_->GetPrototype(desc)->New());
bool ok = protobuf::TextFormat::ParseFromString(text_format_proto, msg.get());
if (!ok) {
LogError("Failed to parse text format to proto.");
return "";
bool ok;
if (is_json_format) {
ok = grpc::protobuf::json::JsonStringToMessage(formatted_proto, msg.get())
.ok();
if (!ok) {
LogError("Failed to convert json format to proto.");
return "";
}
} else {
ok = protobuf::TextFormat::ParseFromString(formatted_proto, msg.get());
if (!ok) {
LogError("Failed to convert text format to proto.");
return "";
}
}
ok = msg->SerializeToString(&serialized);
if (!ok) {
LogError("Failed to serialize proto.");
@ -265,9 +278,9 @@ grpc::string ProtoFileParser::GetSerializedProtoFromMessageType(
return serialized;
}
grpc::string ProtoFileParser::GetTextFormatFromMessageType(
const grpc::string& message_type_name,
const grpc::string& serialized_proto) {
grpc::string ProtoFileParser::GetFormattedStringFromMessageType(
const grpc::string& message_type_name, const grpc::string& serialized_proto,
bool is_json_format) {
has_error_ = false;
const protobuf::Descriptor* desc =
desc_pool_->FindMessageTypeByName(message_type_name);
@ -281,12 +294,24 @@ grpc::string ProtoFileParser::GetTextFormatFromMessageType(
LogError("Failed to deserialize proto.");
return "";
}
grpc::string text_format;
if (!protobuf::TextFormat::PrintToString(*msg.get(), &text_format)) {
LogError("Failed to print proto message to text format");
return "";
grpc::string formatted_string;
if (is_json_format) {
grpc::protobuf::json::JsonPrintOptions jsonPrintOptions;
jsonPrintOptions.add_whitespace = true;
if (!grpc::protobuf::json::MessageToJsonString(
*msg.get(), &formatted_string, jsonPrintOptions)
.ok()) {
LogError("Failed to print proto message to json format");
return "";
}
} else {
if (!protobuf::TextFormat::PrintToString(*msg.get(), &formatted_string)) {
LogError("Failed to print proto message to text format");
return "";
}
}
return text_format;
return formatted_string;
}
void ProtoFileParser::LogError(const grpc::string& error_msg) {

@ -53,21 +53,49 @@ class ProtoFileParser {
// used as the argument of Stub::Call()
grpc::string GetFormattedMethodName(const grpc::string& method);
grpc::string GetSerializedProtoFromMethod(
const grpc::string& method, const grpc::string& text_format_proto,
bool is_request);
grpc::string GetTextFormatFromMethod(const grpc::string& method,
const grpc::string& serialized_proto,
bool is_request);
/// Converts a text or json string to its binary proto representation for the
/// given method's input or return type.
/// \param method the name of the method (does not need to be fully qualified
/// name)
/// \param formatted_proto the text- or json-formatted proto string
/// \param is_request if \c true the resolved type is that of the input
/// parameter of the method, otherwise it is the output type
/// \param is_json_format if \c true the \c formatted_proto is treated as a
/// json-formatted proto, otherwise it is treated as a text-formatted
/// proto
/// \return the serialised binary proto represenation of \c formatted_proto
grpc::string GetSerializedProtoFromMethod(const grpc::string& method,
const grpc::string& formatted_proto,
bool is_request,
bool is_json_format);
/// Converts a text or json string to its proto representation for the given
/// message type.
/// \param formatted_proto the text- or json-formatted proto string
/// \return the serialised binary proto represenation of \c formatted_proto
grpc::string GetSerializedProtoFromMessageType(
const grpc::string& message_type_name,
const grpc::string& text_format_proto);
grpc::string GetTextFormatFromMessageType(
const grpc::string& formatted_proto, bool is_json_format);
/// Converts a binary proto string to its text or json string representation
/// for the given method's input or return type.
/// \param method the name of the method (does not need to be a fully
/// qualified name)
/// \param the serialised binary proto representation of type
/// \c message_type_name
/// \return the text- or json-formatted proto string of \c serialized_proto
grpc::string GetFormattedStringFromMethod(
const grpc::string& method, const grpc::string& serialized_proto,
bool is_request, bool is_json_format);
/// Converts a binary proto string to its text or json string representation
/// for the given message type.
/// \param the serialised binary proto representation of type
/// \c message_type_name
/// \return the text- or json-formatted proto string of \c serialized_proto
grpc::string GetFormattedStringFromMessageType(
const grpc::string& message_type_name,
const grpc::string& serialized_proto);
const grpc::string& serialized_proto, bool is_json_format);
bool IsStreaming(const grpc::string& method, bool is_request);

@ -0,0 +1,25 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 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_e2e_performance_singlevm.sh"
timeout_mins: 360
action {
define_artifacts {
regex: "**/*sponge_log.*"
regex: "**/perf_reports/**"
}
}

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -ex
# Enter the gRPC repo root
cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_perf_multilang_rc
# "smoketest" scenarios on a single VM (=no remote VM for running qps_workers)
tools/run_tests/run_performance_tests.py \
-l c++ csharp ruby java python go php7 php7_protobuf_c node node_purejs \
--netperf \
--category smoketest \
-u kbuilder \
--xml_report reports/singlemachine/sponge_log.xml

@ -1159,7 +1159,7 @@
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "handshake_client",
"name": "handshake_client_ssl",
"src": [
"test/core/handshake/client_ssl.cc"
],
@ -1178,7 +1178,7 @@
],
"is_filegroup": false,
"language": "c",
"name": "handshake_server",
"name": "handshake_server_ssl",
"src": [
"test/core/handshake/server_ssl.cc",
"test/core/handshake/server_ssl_common.cc",
@ -1627,7 +1627,7 @@
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "memory_profile_test",
"name": "memory_usage_test",
"src": [
"test/core/memory_usage/memory_usage_test.cc"
],

@ -1447,7 +1447,7 @@
"flaky": false,
"gtest": false,
"language": "c",
"name": "handshake_client",
"name": "handshake_client_ssl",
"platforms": [
"linux"
],
@ -1467,7 +1467,7 @@
"flaky": false,
"gtest": false,
"language": "c",
"name": "handshake_server",
"name": "handshake_server_ssl",
"platforms": [
"linux"
],
@ -1879,7 +1879,7 @@
"flaky": false,
"gtest": false,
"language": "c",
"name": "memory_profile_test",
"name": "memory_usage_test",
"platforms": [
"linux",
"mac",

@ -825,6 +825,12 @@ class PythonLanguage(object):
minor='6',
bits=bits,
config_vars=config_vars)
python37_config = _python_config_generator(
name='py37',
major='3',
minor='7',
bits=bits,
config_vars=config_vars)
pypy27_config = _pypy_config_generator(
name='pypy', major='2', config_vars=config_vars)
pypy32_config = _pypy_config_generator(
@ -846,6 +852,8 @@ class PythonLanguage(object):
return (python35_config,)
elif args.compiler == 'python3.6':
return (python36_config,)
elif args.compiler == 'python3.7':
return (python37_config,)
elif args.compiler == 'pypy':
return (pypy27_config,)
elif args.compiler == 'pypy3':
@ -858,6 +866,7 @@ class PythonLanguage(object):
python34_config,
python35_config,
python36_config,
python37_config,
)
else:
raise Exception('Compiler %s not supported.' % args.compiler)
@ -1360,9 +1369,9 @@ argp.add_argument(
choices=[
'default', 'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc7.2',
'gcc_musl', 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7', 'clang7.0',
'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3',
'python_alpine', 'all_the_cpythons', 'electron1.3', 'electron1.6',
'coreclr', 'cmake', 'cmake_vs2015', 'cmake_vs2017'
'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7', 'pypy',
'pypy3', 'python_alpine', 'all_the_cpythons', 'electron1.3',
'electron1.6', 'coreclr', 'cmake', 'cmake_vs2015', 'cmake_vs2017'
],
default='default',
help=

Loading…
Cancel
Save