Merge github.com:grpc/grpc into tfix2

pull/13039/head
Craig Tiller 7 years ago
commit 40ad5ea96c
  1. 1
      .clang_complete
  2. 3
      .gitmodules
  3. 2
      BUILD
  4. 434
      CMakeLists.txt
  5. 134
      Makefile
  6. 5
      WORKSPACE
  7. 3
      binding.gyp
  8. 43
      build.yaml
  9. 2
      gRPC-Core.podspec
  10. 1
      grpc.gemspec
  11. 3
      grpc.gyp
  12. 2
      include/grpc++/impl/codegen/call.h
  13. 1
      package.xml
  14. 23
      src/core/ext/transport/chttp2/transport/flow_control.cc
  15. 252
      src/core/ext/transport/chttp2/transport/hpack_encoder.cc
  16. 2
      src/core/ext/transport/chttp2/transport/internal.h
  17. 9
      src/core/lib/iomgr/exec_ctx.cc
  18. 41
      src/core/lib/support/memory.h
  19. 32
      src/core/lib/support/vector.h
  20. 7
      src/core/lib/transport/metadata.cc
  21. 3
      src/core/lib/transport/metadata.h
  22. 53
      src/core/lib/transport/pid_controller.cc
  23. 110
      src/core/lib/transport/pid_controller.h
  24. 4
      src/php/ext/grpc/server.c
  25. 4
      templates/CMakeLists.txt.template
  26. 65
      test/core/debug/stats_test.cc
  27. 26
      test/core/support/BUILD
  28. 42
      test/core/support/vector_test.cc
  29. 5
      test/core/transport/BUILD
  30. 1
      test/core/transport/bdp_estimator_test.cc
  31. 99
      test/core/transport/chttp2/hpack_encoder_test.c
  32. 4
      test/core/transport/metadata_test.c
  33. 78
      test/core/transport/pid_controller_test.c
  34. 91
      test/core/transport/pid_controller_test.cc
  35. 160
      test/cpp/microbenchmarks/bm_chttp2_hpack.cc
  36. 7
      test/cpp/microbenchmarks/helpers.cc
  37. 3
      test/cpp/microbenchmarks/helpers.h
  38. 1
      third_party/abseil-cpp
  39. 13
      tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh
  40. 1
      tools/doxygen/Doxyfile.c++.internal
  41. 1
      tools/doxygen/Doxyfile.core.internal
  42. 2
      tools/internal_ci/helper_scripts/gen_report_index.sh
  43. 1
      tools/internal_ci/helper_scripts/prepare_build_interop_rc
  44. 1
      tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
  45. 2
      tools/interop_matrix/create_matrix_images.py
  46. 8
      tools/run_tests/dockerize/build_interop_image.sh
  47. 57
      tools/run_tests/generated/sources_and_headers.json
  48. 79
      tools/run_tests/generated/tests.json
  49. 2
      tools/run_tests/python_utils/filter_pull_request_tests.py
  50. 12
      tools/run_tests/run_interop_tests.py
  51. 6
      tools/run_tests/run_tests.py
  52. 1
      tools/run_tests/sanity/check_sources_and_headers.py
  53. 1
      tools/run_tests/sanity/check_submodules.sh
  54. 3
      tools/run_tests/sanity/check_test_filtering.py

@ -9,3 +9,4 @@
-Ithird_party/benchmark/include -Ithird_party/benchmark/include
-Ithird_party/zlib -Ithird_party/zlib
-Ithird_party/protobuf/src -Ithird_party/protobuf/src
-Ithird_party/abseil-cpp

3
.gitmodules vendored

@ -27,3 +27,6 @@
[submodule "third_party/bloaty"] [submodule "third_party/bloaty"]
path = third_party/bloaty path = third_party/bloaty
url = https://github.com/google/bloaty.git url = https://github.com/google/bloaty.git
[submodule "third_party/abseil-cpp"]
path = third_party/abseil-cpp
url = https://github.com/abseil/abseil-cpp

@ -515,6 +515,7 @@ grpc_cc_library(
"src/core/lib/support/atomic_with_std.h", "src/core/lib/support/atomic_with_std.h",
"src/core/lib/support/env.h", "src/core/lib/support/env.h",
"src/core/lib/support/memory.h", "src/core/lib/support/memory.h",
"src/core/lib/support/vector.h",
"src/core/lib/support/manual_constructor.h", "src/core/lib/support/manual_constructor.h",
"src/core/lib/support/mpscq.h", "src/core/lib/support/mpscq.h",
"src/core/lib/support/murmur_hash.h", "src/core/lib/support/murmur_hash.h",
@ -529,6 +530,7 @@ grpc_cc_library(
public_hdrs = GPR_PUBLIC_HDRS, public_hdrs = GPR_PUBLIC_HDRS,
deps = [ deps = [
"gpr_codegen", "gpr_codegen",
"@com_google_absl//absl/container:inlined_vector"
], ],
) )

File diff suppressed because it is too large Load Diff

@ -327,7 +327,7 @@ CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
CXXFLAGS += -stdlib=libc++ CXXFLAGS += -stdlib=libc++
endif endif
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp
LDFLAGS += -g LDFLAGS += -g
CPPFLAGS += $(CPPFLAGS_$(CONFIG)) CPPFLAGS += $(CPPFLAGS_$(CONFIG))
@ -1091,7 +1091,6 @@ timer_heap_test: $(BINDIR)/$(CONFIG)/timer_heap_test
timer_list_test: $(BINDIR)/$(CONFIG)/timer_list_test timer_list_test: $(BINDIR)/$(CONFIG)/timer_list_test
transport_connectivity_state_test: $(BINDIR)/$(CONFIG)/transport_connectivity_state_test transport_connectivity_state_test: $(BINDIR)/$(CONFIG)/transport_connectivity_state_test
transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test
transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test
transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test
udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test
uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test
@ -1180,6 +1179,8 @@ streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test stress_test: $(BINDIR)/$(CONFIG)/stress_test
thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test
vector_test: $(BINDIR)/$(CONFIG)/vector_test
writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test
public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test
@ -1472,7 +1473,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/timer_list_test \ $(BINDIR)/$(CONFIG)/timer_list_test \
$(BINDIR)/$(CONFIG)/transport_connectivity_state_test \ $(BINDIR)/$(CONFIG)/transport_connectivity_state_test \
$(BINDIR)/$(CONFIG)/transport_metadata_test \ $(BINDIR)/$(CONFIG)/transport_metadata_test \
$(BINDIR)/$(CONFIG)/transport_pid_controller_test \
$(BINDIR)/$(CONFIG)/transport_security_test \ $(BINDIR)/$(CONFIG)/transport_security_test \
$(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/udp_server_test \
$(BINDIR)/$(CONFIG)/uri_parser_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \
@ -1617,6 +1617,8 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/transport_pid_controller_test \
$(BINDIR)/$(CONFIG)/vector_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/boringssl_aes_test \ $(BINDIR)/$(CONFIG)/boringssl_aes_test \
$(BINDIR)/$(CONFIG)/boringssl_asn1_test \ $(BINDIR)/$(CONFIG)/boringssl_asn1_test \
@ -1739,6 +1741,8 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/transport_pid_controller_test \
$(BINDIR)/$(CONFIG)/vector_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \
$(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_test \
@ -1991,8 +1995,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/transport_connectivity_state_test || ( echo test transport_connectivity_state_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/transport_connectivity_state_test || ( echo test transport_connectivity_state_test failed ; exit 1 )
$(E) "[RUN] Testing transport_metadata_test" $(E) "[RUN] Testing transport_metadata_test"
$(Q) $(BINDIR)/$(CONFIG)/transport_metadata_test || ( echo test transport_metadata_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/transport_metadata_test || ( echo test transport_metadata_test failed ; exit 1 )
$(E) "[RUN] Testing transport_pid_controller_test"
$(Q) $(BINDIR)/$(CONFIG)/transport_pid_controller_test || ( echo test transport_pid_controller_test failed ; exit 1 )
$(E) "[RUN] Testing transport_security_test" $(E) "[RUN] Testing transport_security_test"
$(Q) $(BINDIR)/$(CONFIG)/transport_security_test || ( echo test transport_security_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/transport_security_test || ( echo test transport_security_test failed ; exit 1 )
$(E) "[RUN] Testing udp_server_test" $(E) "[RUN] Testing udp_server_test"
@ -2155,6 +2157,10 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 )
$(E) "[RUN] Testing thread_stress_test" $(E) "[RUN] Testing thread_stress_test"
$(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 )
$(E) "[RUN] Testing transport_pid_controller_test"
$(Q) $(BINDIR)/$(CONFIG)/transport_pid_controller_test || ( echo test transport_pid_controller_test failed ; exit 1 )
$(E) "[RUN] Testing vector_test"
$(Q) $(BINDIR)/$(CONFIG)/vector_test || ( echo test vector_test failed ; exit 1 )
$(E) "[RUN] Testing writes_per_rpc_test" $(E) "[RUN] Testing writes_per_rpc_test"
$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
$(E) "[RUN] Testing resolver_component_tests_runner_invoker_unsecure" $(E) "[RUN] Testing resolver_component_tests_runner_invoker_unsecure"
@ -13419,38 +13425,6 @@ endif
endif endif
TRANSPORT_PID_CONTROLLER_TEST_SRC = \
test/core/transport/pid_controller_test.c \
TRANSPORT_PID_CONTROLLER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_PID_CONTROLLER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/transport_pid_controller_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_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) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
endif
endif
TRANSPORT_SECURITY_TEST_SRC = \ TRANSPORT_SECURITY_TEST_SRC = \
test/core/tsi/transport_security_test.c \ test/core/tsi/transport_security_test.c \
@ -17201,6 +17175,92 @@ endif
endif endif
TRANSPORT_PID_CONTROLLER_TEST_SRC = \
test/core/transport/pid_controller_test.cc \
TRANSPORT_PID_CONTROLLER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_PID_CONTROLLER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/transport_pid_controller_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)/transport_pid_controller_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep)
endif
endif
VECTOR_TEST_SRC = \
test/core/support/vector_test.cc \
VECTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(VECTOR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/vector_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)/vector_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/vector_test: $(PROTOBUF_DEP) $(VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/vector_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/support/vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_vector_test: $(VECTOR_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(VECTOR_TEST_OBJS:.o=.dep)
endif
endif
WRITES_PER_RPC_TEST_SRC = \ WRITES_PER_RPC_TEST_SRC = \
test/cpp/performance/writes_per_rpc_test.cc \ test/cpp/performance/writes_per_rpc_test.cc \

@ -92,3 +92,8 @@ new_local_repository(
path = "third_party/cares", path = "third_party/cares",
build_file = "third_party/cares/cares.BUILD", build_file = "third_party/cares/cares.BUILD",
) )
local_repository(
name = "com_google_absl",
path = "third_party/abseil-cpp",
)

@ -63,6 +63,7 @@
'-Wno-long-long', '-Wno-long-long',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-DOSATOMIC_USE_INLINED=1', '-DOSATOMIC_USE_INLINED=1',
'-Ithird_party/abseil-cpp',
], ],
'ldflags': [ 'ldflags': [
'-g', '-g',
@ -184,6 +185,7 @@
'-Wno-long-long', '-Wno-long-long',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-DOSATOMIC_USE_INLINED=1', '-DOSATOMIC_USE_INLINED=1',
'-Ithird_party/abseil-cpp',
], ],
'OTHER_CPLUSPLUSFLAGS': [ 'OTHER_CPLUSPLUSFLAGS': [
'-g', '-g',
@ -193,6 +195,7 @@
'-Wno-long-long', '-Wno-long-long',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-DOSATOMIC_USE_INLINED=1', '-DOSATOMIC_USE_INLINED=1',
'-Ithird_party/abseil-cpp',
'-stdlib=libc++', '-stdlib=libc++',
'-std=c++11', '-std=c++11',
'-Wno-error=deprecated-declarations' '-Wno-error=deprecated-declarations'

@ -427,6 +427,7 @@ filegroups:
- src/core/lib/slice/slice_hash_table.h - src/core/lib/slice/slice_hash_table.h
- src/core/lib/slice/slice_internal.h - src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_string_helpers.h - src/core/lib/slice/slice_string_helpers.h
- src/core/lib/support/vector.h
- src/core/lib/surface/alarm_internal.h - src/core/lib/surface/alarm_internal.h
- src/core/lib/surface/api_trace.h - src/core/lib/surface/api_trace.h
- src/core/lib/surface/call.h - src/core/lib/surface/call.h
@ -3405,18 +3406,6 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
uses_polling: false
- name: transport_pid_controller_test
build: test
language: c
src:
- test/core/transport/pid_controller_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
uses_polling: false
- name: transport_security_test - name: transport_security_test
build: test build: test
language: c language: c
@ -4705,6 +4694,9 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
exclude_configs:
- tsan
timeout_seconds: 1200
uses_polling: false uses_polling: false
- name: status_test - name: status_test
build: test build: test
@ -4787,6 +4779,32 @@ targets:
- gpr_test_util - gpr_test_util
- gpr - gpr
timeout_seconds: 1200 timeout_seconds: 1200
- name: transport_pid_controller_test
build: test
language: c++
src:
- test/core/transport/pid_controller_test.cc
deps:
- grpc++_test_util
- grpc++
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: vector_test
gtest: true
build: test
language: c++
src:
- test/core/support/vector_test.cc
deps:
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
uses:
- grpc++_test
- name: writes_per_rpc_test - name: writes_per_rpc_test
gtest: true gtest: true
cpu_cost: 0.5 cpu_cost: 0.5
@ -4968,6 +4986,7 @@ defaults:
-D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
global: global:
CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
-Ithird_party/abseil-cpp
LDFLAGS: -g LDFLAGS: -g
zlib: zlib:
CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration

@ -409,6 +409,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h', 'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h', 'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h', 'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/support/vector.h',
'src/core/lib/surface/alarm_internal.h', 'src/core/lib/surface/alarm_internal.h',
'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h', 'src/core/lib/surface/call.h',
@ -910,6 +911,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h', 'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h', 'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h', 'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/support/vector.h',
'src/core/lib/surface/alarm_internal.h', 'src/core/lib/surface/alarm_internal.h',
'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h', 'src/core/lib/surface/call.h',

@ -341,6 +341,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/slice_hash_table.h ) s.files += %w( src/core/lib/slice/slice_hash_table.h )
s.files += %w( src/core/lib/slice/slice_internal.h ) s.files += %w( src/core/lib/slice/slice_internal.h )
s.files += %w( src/core/lib/slice/slice_string_helpers.h ) s.files += %w( src/core/lib/slice/slice_string_helpers.h )
s.files += %w( src/core/lib/support/vector.h )
s.files += %w( src/core/lib/surface/alarm_internal.h ) s.files += %w( src/core/lib/surface/alarm_internal.h )
s.files += %w( src/core/lib/surface/api_trace.h ) s.files += %w( src/core/lib/surface/api_trace.h )
s.files += %w( src/core/lib/surface/call.h ) s.files += %w( src/core/lib/surface/call.h )

@ -57,6 +57,7 @@
'-Wno-long-long', '-Wno-long-long',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-DOSATOMIC_USE_INLINED=1', '-DOSATOMIC_USE_INLINED=1',
'-Ithird_party/abseil-cpp',
], ],
'ldflags': [ 'ldflags': [
'-g', '-g',
@ -134,6 +135,7 @@
'-Wno-long-long', '-Wno-long-long',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-DOSATOMIC_USE_INLINED=1', '-DOSATOMIC_USE_INLINED=1',
'-Ithird_party/abseil-cpp',
], ],
'OTHER_CPLUSPLUSFLAGS': [ 'OTHER_CPLUSPLUSFLAGS': [
'-g', '-g',
@ -143,6 +145,7 @@
'-Wno-long-long', '-Wno-long-long',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-DOSATOMIC_USE_INLINED=1', '-DOSATOMIC_USE_INLINED=1',
'-Ithird_party/abseil-cpp',
'-stdlib=libc++', '-stdlib=libc++',
'-std=c++11', '-std=c++11',
'-Wno-error=deprecated-declarations' '-Wno-error=deprecated-declarations'

@ -163,7 +163,7 @@ class WriteOptions {
/// Clears flag indicating that this is the last message in a stream, /// Clears flag indicating that this is the last message in a stream,
/// disabling coalescing. /// disabling coalescing.
inline WriteOptions& clear_last_messsage() { inline WriteOptions& clear_last_message() {
last_message_ = false; last_message_ = false;
return *this; return *this;
} }

@ -353,6 +353,7 @@
<file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/vector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/alarm_internal.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/surface/alarm_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />

@ -399,22 +399,19 @@ static double get_pid_controller_guess(grpc_exec_ctx* exec_ctx,
if (!tfc->pid_controller_initialized) { if (!tfc->pid_controller_initialized) {
tfc->last_pid_update = now; tfc->last_pid_update = now;
tfc->pid_controller_initialized = true; tfc->pid_controller_initialized = true;
grpc_pid_controller_args args; tfc->pid_controller.Init(grpc_core::PidController::Args()
memset(&args, 0, sizeof(args)); .set_gain_p(4)
args.gain_p = 4; .set_gain_i(8)
args.gain_i = 8; .set_gain_d(0)
args.gain_d = 0; .set_initial_control_value(target)
args.initial_control_value = target; .set_min_control_value(-1)
args.min_control_value = -1; .set_max_control_value(25)
args.max_control_value = 25; .set_integral_range(10));
args.integral_range = 10;
grpc_pid_controller_init(&tfc->pid_controller, args);
return pow(2, target); return pow(2, target);
} }
double bdp_error = target - grpc_pid_controller_last(&tfc->pid_controller); double bdp_error = target - tfc->pid_controller->last_control_value();
double dt = (double)(now - tfc->last_pid_update) * 1e-3; double dt = (double)(now - tfc->last_pid_update) * 1e-3;
double log2_bdp_guess = double log2_bdp_guess = tfc->pid_controller->Update(bdp_error, dt);
grpc_pid_controller_update(&tfc->pid_controller, bdp_error, dt);
tfc->last_pid_update = now; tfc->last_pid_update = now;
return pow(2, log2_bdp_guess); return pow(2, log2_bdp_guess);
} }

@ -178,24 +178,19 @@ static void evict_entry(grpc_chttp2_hpack_compressor *c) {
c->table_elems--; c->table_elems--;
} }
/* add an element to the decoder table */ // Reserve space in table for the new element, evict entries if needed.
static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, // Return the new index of the element. Return 0 to indicate not adding to
grpc_mdelem elem) { // table.
GPR_ASSERT(GRPC_MDELEM_IS_INTERNED(elem)); static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor *c,
size_t elem_size) {
uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
uint32_t new_index = c->tail_remote_index + c->table_elems + 1; uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
GPR_ASSERT(elem_size < 65536); GPR_ASSERT(elem_size < 65536);
if (elem_size > c->max_table_size) { if (elem_size > c->max_table_size) {
while (c->table_size > 0) { while (c->table_size > 0) {
evict_entry(c); evict_entry(c);
} }
return; return 0;
} }
/* Reserve space for this element in the remote table: if this overflows /* Reserve space for this element in the remote table: if this overflows
@ -209,37 +204,26 @@ static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
c->table_size = (uint16_t)(c->table_size + elem_size); c->table_size = (uint16_t)(c->table_size + elem_size);
c->table_elems++; c->table_elems++;
/* Store this element into {entries,indices}_elem */ return new_index;
if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem)) { }
/* already there: update with new index */
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; /* dummy function */
} else if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], static void add_nothing(grpc_exec_ctx *exec_ctx,
elem)) { grpc_chttp2_hpack_compressor *c, grpc_mdelem elem,
/* already there (cuckoo): update with new index */ size_t elem_size) {}
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
} else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_2(elem_hash)])) { // Add a key to the dynamic table. Both key and value will be added to table at
/* not there, but a free element: add */ // the decoder.
c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem); static void add_key_with_index(grpc_exec_ctx *exec_ctx,
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; grpc_chttp2_hpack_compressor *c,
} else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_3(elem_hash)])) { grpc_mdelem elem, uint32_t new_index) {
/* not there (cuckoo), but a free element: add */ if (new_index == 0) {
c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem); return;
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
} else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
/* not there: replace oldest */
GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
} else {
/* not there: replace oldest */
GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
} }
/* do exactly the same for the key (so we can find by that again too) */ uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
/* Store the key into {entries,indices}_keys */
if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)], if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)],
GRPC_MDKEY(elem))) { GRPC_MDKEY(elem))) {
c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
@ -272,6 +256,63 @@ static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
} }
} }
/* add an element to the decoder table */
static void add_elem_with_index(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c,
grpc_mdelem elem, uint32_t new_index) {
if (new_index == 0) {
return;
}
GPR_ASSERT(GRPC_MDELEM_IS_INTERNED(elem));
uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
/* Store this element into {entries,indices}_elem */
if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem)) {
/* already there: update with new index */
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
} else if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)],
elem)) {
/* already there (cuckoo): update with new index */
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
} else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_2(elem_hash)])) {
/* not there, but a free element: add */
c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
} else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_3(elem_hash)])) {
/* not there (cuckoo), but a free element: add */
c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
} else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
/* not there: replace oldest */
GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
} else {
/* not there: replace oldest */
GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
}
add_key_with_index(exec_ctx, c, elem, new_index);
}
static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
grpc_mdelem elem, size_t elem_size) {
uint32_t new_index = prepare_space_for_new_elem(c, elem_size);
add_elem_with_index(exec_ctx, c, elem, new_index);
}
static void add_key(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
grpc_mdelem elem, size_t elem_size) {
uint32_t new_index = prepare_space_for_new_elem(c, elem_size);
add_key_with_index(exec_ctx, c, elem, new_index);
}
static void emit_indexed(grpc_exec_ctx *exec_ctx, static void emit_indexed(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c, uint32_t elem_index, grpc_chttp2_hpack_compressor *c, uint32_t elem_index,
framer_state *st) { framer_state *st) {
@ -363,7 +404,9 @@ static void emit_lithdr_noidx(grpc_exec_ctx *exec_ctx,
static void emit_lithdr_incidx_v(grpc_exec_ctx *exec_ctx, static void emit_lithdr_incidx_v(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c, grpc_chttp2_hpack_compressor *c,
grpc_mdelem elem, framer_state *st) { uint32_t unused_index, grpc_mdelem elem,
framer_state *st) {
GPR_ASSERT(unused_index == 0);
GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V(exec_ctx); GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V(exec_ctx);
GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx); GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx);
uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
@ -385,7 +428,9 @@ static void emit_lithdr_incidx_v(grpc_exec_ctx *exec_ctx,
static void emit_lithdr_noidx_v(grpc_exec_ctx *exec_ctx, static void emit_lithdr_noidx_v(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c, grpc_chttp2_hpack_compressor *c,
grpc_mdelem elem, framer_state *st) { uint32_t unused_index, grpc_mdelem elem,
framer_state *st) {
GPR_ASSERT(unused_index == 0);
GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V(exec_ctx); GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V(exec_ctx);
GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx); GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx);
uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
@ -430,9 +475,14 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
"Reserved header (colon-prefixed) happening after regular ones."); "Reserved header (colon-prefixed) happening after regular ones.");
} }
if (GRPC_TRACER_ON(grpc_http_trace) && !GRPC_MDELEM_IS_INTERNED(elem)) { if (GRPC_TRACER_ON(grpc_http_trace)) {
char *k = grpc_slice_to_c_string(GRPC_MDKEY(elem)); char *k = grpc_slice_to_c_string(GRPC_MDKEY(elem));
char *v = grpc_slice_to_c_string(GRPC_MDVALUE(elem)); char *v = NULL;
if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
v = grpc_dump_slice(GRPC_MDVALUE(elem), GPR_DUMP_HEX);
} else {
v = grpc_slice_to_c_string(GRPC_MDVALUE(elem));
}
gpr_log( gpr_log(
GPR_DEBUG, GPR_DEBUG,
"Encode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d", "Encode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
@ -442,64 +492,70 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
gpr_free(k); gpr_free(k);
gpr_free(v); gpr_free(v);
} }
if (!GRPC_MDELEM_IS_INTERNED(elem)) {
emit_lithdr_noidx_v(exec_ctx, c, elem, st); bool elem_interned = GRPC_MDELEM_IS_INTERNED(elem);
bool key_interned = elem_interned || grpc_slice_is_interned(GRPC_MDKEY(elem));
// Key is not interned, emit literals.
if (!key_interned) {
emit_lithdr_noidx_v(exec_ctx, c, 0, elem, st);
return; return;
} }
uint32_t key_hash; uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
uint32_t value_hash; uint32_t elem_hash = 0;
uint32_t elem_hash;
size_t decoder_space_usage;
uint32_t indices_key;
int should_add_elem;
key_hash = grpc_slice_hash(GRPC_MDKEY(elem)); if (elem_interned) {
value_hash = grpc_slice_hash(GRPC_MDVALUE(elem)); uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash); elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems); inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum,
c->filter_elems);
/* is this elem currently in the decoders table? */ /* is this elem currently in the decoders table? */
if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem) && if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem) &&
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) { c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) {
/* HIT: complete element (first cuckoo hash) */ /* HIT: complete element (first cuckoo hash) */
emit_indexed(exec_ctx, c, emit_indexed(exec_ctx, c,
dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), st); dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), st);
return; return;
} }
if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem) && if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem) &&
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) { c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) {
/* HIT: complete element (second cuckoo hash) */ /* HIT: complete element (second cuckoo hash) */
emit_indexed(exec_ctx, c, emit_indexed(exec_ctx, c,
dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), st); dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), st);
return; return;
}
} }
uint32_t indices_key;
/* should this elem be in the table? */ /* should this elem be in the table? */
decoder_space_usage = grpc_mdelem_get_size_in_hpack_table(elem); size_t decoder_space_usage =
should_add_elem = decoder_space_usage < MAX_DECODER_SPACE_USAGE && grpc_mdelem_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= bool should_add_elem = elem_interned &&
c->filter_elems_sum / ONE_ON_ADD_PROBABILITY; decoder_space_usage < MAX_DECODER_SPACE_USAGE &&
c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >=
c->filter_elems_sum / ONE_ON_ADD_PROBABILITY;
void (*maybe_add)(grpc_exec_ctx *, grpc_chttp2_hpack_compressor *,
grpc_mdelem, size_t) =
should_add_elem ? add_elem : add_nothing;
void (*emit)(grpc_exec_ctx *, grpc_chttp2_hpack_compressor *, uint32_t,
grpc_mdelem, framer_state *) =
should_add_elem ? emit_lithdr_incidx : emit_lithdr_noidx;
/* no hits for the elem... maybe there's a key? */ /* no hits for the elem... maybe there's a key? */
indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)]; indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)];
if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)], if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)],
GRPC_MDKEY(elem)) && GRPC_MDKEY(elem)) &&
indices_key > c->tail_remote_index) { indices_key > c->tail_remote_index) {
/* HIT: key (first cuckoo hash) */ /* HIT: key (first cuckoo hash) */
if (should_add_elem) { emit(exec_ctx, c, dynidx(c, indices_key), elem, st);
emit_lithdr_incidx(exec_ctx, c, dynidx(c, indices_key), elem, st); maybe_add(exec_ctx, c, elem, decoder_space_usage);
add_elem(exec_ctx, c, elem); return;
return;
} else {
emit_lithdr_noidx(exec_ctx, c, dynidx(c, indices_key), elem, st);
return;
}
GPR_UNREACHABLE_CODE(return );
} }
indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)];
@ -507,28 +563,20 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
GRPC_MDKEY(elem)) && GRPC_MDKEY(elem)) &&
indices_key > c->tail_remote_index) { indices_key > c->tail_remote_index) {
/* HIT: key (first cuckoo hash) */ /* HIT: key (first cuckoo hash) */
if (should_add_elem) { emit(exec_ctx, c, dynidx(c, indices_key), elem, st);
emit_lithdr_incidx(exec_ctx, c, dynidx(c, indices_key), elem, st); maybe_add(exec_ctx, c, elem, decoder_space_usage);
add_elem(exec_ctx, c, elem); return;
return;
} else {
emit_lithdr_noidx(exec_ctx, c, dynidx(c, indices_key), elem, st);
return;
}
GPR_UNREACHABLE_CODE(return );
} }
/* no elem, key in the table... fall back to literal emission */ /* no elem, key in the table... fall back to literal emission */
bool should_add_key =
if (should_add_elem) { !elem_interned && decoder_space_usage < MAX_DECODER_SPACE_USAGE;
emit_lithdr_incidx_v(exec_ctx, c, elem, st); emit = (should_add_elem || should_add_key) ? emit_lithdr_incidx_v
add_elem(exec_ctx, c, elem); : emit_lithdr_noidx_v;
return; maybe_add =
} else { should_add_elem ? add_elem : (should_add_key ? add_key : add_nothing);
emit_lithdr_noidx_v(exec_ctx, c, elem, st); emit(exec_ctx, c, 0, elem, st);
return; maybe_add(exec_ctx, c, elem, decoder_space_usage);
}
GPR_UNREACHABLE_CODE(return );
} }
#define STRLEN_LIT(x) (sizeof(x) - 1) #define STRLEN_LIT(x) (sizeof(x) - 1)

@ -273,7 +273,7 @@ typedef struct {
/* pid controller */ /* pid controller */
bool pid_controller_initialized; bool pid_controller_initialized;
grpc_pid_controller pid_controller; grpc_core::ManualConstructor<grpc_core::PidController> pid_controller;
grpc_millis last_pid_update; grpc_millis last_pid_update;
// pointer back to transport for tracing // pointer back to transport for tracing

@ -152,6 +152,15 @@ void grpc_exec_ctx_invalidate_now(grpc_exec_ctx *exec_ctx) {
gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_timespec grpc_millis_to_timespec(grpc_millis millis,
gpr_clock_type clock_type) { gpr_clock_type clock_type) {
// special-case infinities as grpc_millis can be 32bit on some platforms
// while gpr_time_from_millis always takes an int64_t.
if (millis == GRPC_MILLIS_INF_FUTURE) {
return gpr_inf_future(clock_type);
}
if (millis == GRPC_MILLIS_INF_PAST) {
return gpr_inf_past(clock_type);
}
if (clock_type == GPR_TIMESPAN) { if (clock_type == GPR_TIMESPAN) {
return gpr_time_from_millis(millis, GPR_TIMESPAN); return gpr_time_from_millis(millis, GPR_TIMESPAN);
} }

@ -21,6 +21,7 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <limits>
#include <memory> #include <memory>
#include <utility> #include <utility>
@ -54,6 +55,46 @@ inline UniquePtr<T> MakeUnique(Args&&... args) {
return UniquePtr<T>(New<T>(std::forward<Args>(args)...)); return UniquePtr<T>(New<T>(std::forward<Args>(args)...));
} }
// an allocator that uses gpr_malloc/gpr_free
template <class T>
class Allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::false_type propagate_on_container_move_assignment;
template <class U>
struct rebind {
typedef Allocator<U> other;
};
typedef std::true_type is_always_equal;
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
pointer allocate(std::size_t n,
std::allocator<void>::const_pointer hint = 0) {
return static_cast<pointer>(gpr_malloc(n * sizeof(T)));
}
void deallocate(T* p, std::size_t n) { gpr_free(p); }
size_t max_size() const {
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
void construct(pointer p, const_reference val) { new ((void*)p) T(val); }
template <class U, class... Args>
void construct(U* p, Args&&... args) {
::new ((void*)p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) { p->~T(); }
template <class U>
void destroy(U* p) {
p->~U();
}
};
} // namespace grpc_core } // namespace grpc_core
#endif /* GRPC_CORE_LIB_SUPPORT_MEMORY_H */ #endif /* GRPC_CORE_LIB_SUPPORT_MEMORY_H */

@ -0,0 +1,32 @@
/*
*
* Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_SUPPORT_VECTOR_H
#define GRPC_CORE_LIB_SUPPORT_VECTOR_H
#include "absl/container/inlined_vector.h"
#include "src/core/lib/support/memory.h"
namespace grpc_core {
template <typename T, size_t N>
using InlinedVector = absl::InlinedVector<T, N, Allocator<T>>;
} // namespace grpc_core
#endif

@ -352,11 +352,14 @@ static size_t get_base64_encoded_size(size_t raw_length) {
return raw_length / 3 * 4 + tail_xtra[raw_length % 3]; return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
} }
size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem) { size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem,
bool use_true_binary_metadata) {
size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem)); size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
if (grpc_is_binary_header(GRPC_MDKEY(elem))) { if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
return overhead_and_key + get_base64_encoded_size(value_len); return overhead_and_key + (use_true_binary_metadata
? value_len + 1
: get_base64_encoded_size(value_len));
} else { } else {
return overhead_and_key + value_len; return overhead_and_key + value_len;
} }

@ -132,7 +132,8 @@ grpc_mdelem grpc_mdelem_create(
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem); size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem,
bool use_true_binary_metadata);
/* Mutator and accessor for grpc_mdelem user data. The destructor function /* Mutator and accessor for grpc_mdelem user data. The destructor function
is used as a type tag and is checked during user_data fetch. */ is used as a type tag and is checked during user_data fetch. */

@ -19,45 +19,30 @@
#include "src/core/lib/transport/pid_controller.h" #include "src/core/lib/transport/pid_controller.h"
#include <grpc/support/useful.h> #include <grpc/support/useful.h>
void grpc_pid_controller_init(grpc_pid_controller *pid_controller, namespace grpc_core {
grpc_pid_controller_args args) {
pid_controller->args = args;
pid_controller->last_control_value = args.initial_control_value;
grpc_pid_controller_reset(pid_controller);
}
void grpc_pid_controller_reset(grpc_pid_controller *pid_controller) { PidController::PidController(const Args &args)
pid_controller->last_error = 0.0; : last_control_value_(args.initial_control_value()), args_(args) {}
pid_controller->last_dc_dt = 0.0;
pid_controller->error_integral = 0.0;
}
double grpc_pid_controller_update(grpc_pid_controller *pid_controller, double PidController::Update(double error, double dt) {
double error, double dt) { if (dt <= 0) return last_control_value_;
if (dt == 0) return pid_controller->last_control_value;
/* integrate error using the trapezoid rule */ /* integrate error using the trapezoid rule */
pid_controller->error_integral += error_integral_ += dt * (last_error_ + error) * 0.5;
dt * (pid_controller->last_error + error) * 0.5; error_integral_ = GPR_CLAMP(error_integral_, -args_.integral_range(),
pid_controller->error_integral = GPR_CLAMP( args_.integral_range());
pid_controller->error_integral, -pid_controller->args.integral_range, double diff_error = (error - last_error_) / dt;
pid_controller->args.integral_range);
double diff_error = (error - pid_controller->last_error) / dt;
/* calculate derivative of control value vs time */ /* calculate derivative of control value vs time */
double dc_dt = pid_controller->args.gain_p * error + double dc_dt = args_.gain_p() * error + args_.gain_i() * error_integral_ +
pid_controller->args.gain_i * pid_controller->error_integral + args_.gain_d() * diff_error;
pid_controller->args.gain_d * diff_error;
/* and perform trapezoidal integration */ /* and perform trapezoidal integration */
double new_control_value = pid_controller->last_control_value + double new_control_value =
dt * (pid_controller->last_dc_dt + dc_dt) * 0.5; last_control_value_ + dt * (last_dc_dt_ + dc_dt) * 0.5;
new_control_value = new_control_value = GPR_CLAMP(new_control_value, args_.min_control_value(),
GPR_CLAMP(new_control_value, pid_controller->args.min_control_value, args_.max_control_value());
pid_controller->args.max_control_value); last_error_ = error;
pid_controller->last_error = error; last_dc_dt_ = dc_dt;
pid_controller->last_dc_dt = dc_dt; last_control_value_ = new_control_value;
pid_controller->last_control_value = new_control_value;
return new_control_value; return new_control_value;
} }
double grpc_pid_controller_last(grpc_pid_controller *pid_controller) { } // namespace grpc_core
return pid_controller->last_control_value;
}

@ -19,9 +19,7 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H #ifndef GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H
#define GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H #define GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H
#ifdef __cplusplus #include <limits>
extern "C" {
#endif
/* \file Simple PID controller. /* \file Simple PID controller.
Implements a proportional-integral-derivative controller. Implements a proportional-integral-derivative controller.
@ -30,41 +28,87 @@ extern "C" {
Gains can be set to adjust sensitivity to current error (p), the integral Gains can be set to adjust sensitivity to current error (p), the integral
of error (i), and the derivative of error (d). */ of error (i), and the derivative of error (d). */
typedef struct { namespace grpc_core {
double gain_p;
double gain_i;
double gain_d;
double initial_control_value;
double min_control_value;
double max_control_value;
double integral_range;
} grpc_pid_controller_args;
typedef struct { class PidController {
double last_error; public:
double error_integral; class Args {
double last_control_value; public:
double last_dc_dt; double gain_p() const { return gain_p_; }
grpc_pid_controller_args args; double gain_i() const { return gain_i_; }
} grpc_pid_controller; double gain_d() const { return gain_d_; }
double initial_control_value() const { return initial_control_value_; }
double min_control_value() const { return min_control_value_; }
double max_control_value() const { return max_control_value_; }
double integral_range() const { return integral_range_; }
/** Initialize the controller */ Args& set_gain_p(double gain_p) {
void grpc_pid_controller_init(grpc_pid_controller *pid_controller, gain_p_ = gain_p;
grpc_pid_controller_args args); return *this;
}
Args& set_gain_i(double gain_i) {
gain_i_ = gain_i;
return *this;
}
Args& set_gain_d(double gain_d) {
gain_d_ = gain_d;
return *this;
}
Args& set_initial_control_value(double initial_control_value) {
initial_control_value_ = initial_control_value;
return *this;
}
Args& set_min_control_value(double min_control_value) {
min_control_value_ = min_control_value;
return *this;
}
Args& set_max_control_value(double max_control_value) {
max_control_value_ = max_control_value;
return *this;
}
Args& set_integral_range(double integral_range) {
integral_range_ = integral_range;
return *this;
}
/** Reset the controller: useful when things have changed significantly */ private:
void grpc_pid_controller_reset(grpc_pid_controller *pid_controller); double gain_p_ = 0.0;
double gain_i_ = 0.0;
double gain_d_ = 0.0;
double initial_control_value_ = 0.0;
double min_control_value_ = std::numeric_limits<double>::min();
double max_control_value_ = std::numeric_limits<double>::max();
double integral_range_ = std::numeric_limits<double>::max();
};
/** Update the controller: given a current error estimate, and the time since explicit PidController(const Args& args);
the last update, returns a new control value */
double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
double error, double dt);
/** Returns the last control value calculated */ /// Reset the controller internal state: useful when the environment has
double grpc_pid_controller_last(grpc_pid_controller *pid_controller); /// changed significantly
void Reset() {
last_error_ = 0.0;
last_dc_dt_ = 0.0;
error_integral_ = 0.0;
}
#ifdef __cplusplus /// Update the controller: given a current error estimate, and the time since
} /// the last update, returns a new control value
#endif double Update(double error, double dt);
/// Returns the last control value calculated
double last_control_value() const { return last_control_value_; }
/// Returns the current error integral (mostly for testing)
double error_integral() const { return error_integral_; }
private:
double last_error_ = 0.0;
double error_integral_ = 0.0;
double last_control_value_;
double last_dc_dt_ = 0.0;
const Args args_;
};
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */ #endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */

@ -169,7 +169,7 @@ PHP_METHOD(Server, requestCall) {
/** /**
* Add a http2 over tcp listener. * Add a http2 over tcp listener.
* @param string $addr The address to add * @param string $addr The address to add
* @return bool True on success, false on failure * @return int Port on success, 0 on failure
*/ */
PHP_METHOD(Server, addHttp2Port) { PHP_METHOD(Server, addHttp2Port) {
const char *addr; const char *addr;
@ -190,7 +190,7 @@ PHP_METHOD(Server, addHttp2Port) {
* Add a secure http2 over tcp listener. * Add a secure http2 over tcp listener.
* @param string $addr The address to add * @param string $addr The address to add
* @param ServerCredentials The ServerCredentials object * @param ServerCredentials The ServerCredentials object
* @return bool True on success, false on failure * @return int Port on success, 0 on failure
*/ */
PHP_METHOD(Server, addSecureHttp2Port) { PHP_METHOD(Server, addSecureHttp2Port) {
const char *addr; const char *addr;

@ -73,7 +73,7 @@
set(PACKAGE_TARNAME "<%text>${PACKAGE_NAME}-${PACKAGE_VERSION}</%text>") set(PACKAGE_TARNAME "<%text>${PACKAGE_NAME}-${PACKAGE_VERSION}</%text>")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
project(<%text>${PACKAGE_NAME}</%text> C CXX) project(<%text>${PACKAGE_NAME}</%text> C CXX)
set(gRPC_INSTALL_BINDIR "<%text>${CMAKE_INSTALL_PREFIX}</%text>/bin" CACHE PATH "Installation directory for executables") set(gRPC_INSTALL_BINDIR "<%text>${CMAKE_INSTALL_PREFIX}</%text>/bin" CACHE PATH "Installation directory for executables")
set(gRPC_INSTALL_LIBDIR "<%text>${CMAKE_INSTALL_PREFIX}</%text>/lib" CACHE PATH "Installation directory for libraries") set(gRPC_INSTALL_LIBDIR "<%text>${CMAKE_INSTALL_PREFIX}</%text>/lib" CACHE PATH "Installation directory for libraries")
set(gRPC_INSTALL_INCLUDEDIR "<%text>${CMAKE_INSTALL_PREFIX}</%text>/include" CACHE PATH "Installation directory for headers") set(gRPC_INSTALL_INCLUDEDIR "<%text>${CMAKE_INSTALL_PREFIX}</%text>/include" CACHE PATH "Installation directory for headers")
@ -522,6 +522,7 @@
PRIVATE <%text>${CARES_INCLUDE_DIR}</%text> PRIVATE <%text>${CARES_INCLUDE_DIR}</%text>
PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/cares/cares PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/cares/cares
PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include
PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/abseil-cpp
% if lib.build in ['test', 'private'] and lib.language == 'c++': % if lib.build in ['test', 'private'] and lib.language == 'c++':
PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest PRIVATE third_party/googletest/googletest
@ -593,6 +594,7 @@
PRIVATE <%text>${CARES_INCLUDE_DIR}</%text> PRIVATE <%text>${CARES_INCLUDE_DIR}</%text>
PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/cares/cares PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/cares/cares
PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include
PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/abseil-cpp
% if tgt.build in ['test', 'private'] and tgt.language == 'c++': % if tgt.build in ['test', 'private'] and tgt.language == 'c++':
PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest PRIVATE third_party/googletest/googletest

@ -20,7 +20,11 @@ extern "C" {
#include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/stats.h"
} }
#include <mutex>
#include <thread>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -79,38 +83,59 @@ static int FindExpectedBucket(int i, int j) {
grpc_stats_histo_bucket_boundaries[i] - 1; grpc_stats_histo_bucket_boundaries[i] - 1;
} }
TEST(StatsTest, IncHistogram) { class HistogramTest : public ::testing::TestWithParam<int> {};
for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
std::vector<int> test_values; TEST_P(HistogramTest, IncHistogram) {
for (int j = -1000; const int kHistogram = GetParam();
j < std::vector<std::thread> threads;
grpc_stats_histo_bucket_boundaries[i] int cur_bucket = 0;
[grpc_stats_histo_buckets[i] - 1] + auto run = [kHistogram](const std::vector<int>& test_values,
1000; int expected_bucket) {
j++) { gpr_log(GPR_DEBUG, "expected_bucket:%d nvalues=%" PRIdPTR, expected_bucket,
test_values.push_back(j); test_values.size());
}
std::random_shuffle(test_values.begin(), test_values.end());
if (test_values.size() > 10000) {
test_values.resize(10000);
}
for (auto j : test_values) { for (auto j : test_values) {
Snapshot snapshot; Snapshot snapshot;
int expected_bucket = FindExpectedBucket(i, j);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_stats_inc_histogram[i](&exec_ctx, j); grpc_stats_inc_histogram[kHistogram](&exec_ctx, j);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
auto delta = snapshot.delta(); auto delta = snapshot.delta();
EXPECT_EQ(delta.histograms[grpc_stats_histo_start[i] + expected_bucket], EXPECT_EQ(
1); delta
.histograms[grpc_stats_histo_start[kHistogram] + expected_bucket],
1)
<< "\nhistogram:" << kHistogram
<< "\nexpected_bucket:" << expected_bucket << "\nj:" << j;
}
};
std::vector<int> test_values;
for (int j = -1000;
j <
grpc_stats_histo_bucket_boundaries[kHistogram]
[grpc_stats_histo_buckets[kHistogram] -
1] +
1000;
j++) {
int expected_bucket = FindExpectedBucket(kHistogram, j);
if (cur_bucket != expected_bucket) {
threads.emplace_back(
[test_values, run, cur_bucket]() { run(test_values, cur_bucket); });
cur_bucket = expected_bucket;
test_values.clear();
} }
test_values.push_back(j);
}
run(test_values, cur_bucket);
for (auto& t : threads) {
t.join();
} }
} }
INSTANTIATE_TEST_CASE_P(HistogramTestCases, HistogramTest,
::testing::Range<int>(0, GRPC_STATS_HISTOGRAM_COUNT));
} // namespace testing } // namespace testing
} // namespace grpc } // namespace grpc

@ -197,3 +197,29 @@ grpc_cc_test(
"//test/core/util:gpr_test_util", "//test/core/util:gpr_test_util",
], ],
) )
grpc_cc_test(
name = "memory_test",
srcs = ["memory_test.cc"],
language = "C++",
deps = [
"//:grpc",
"//test/core/util:gpr_test_util",
],
external_deps = [
"gtest",
],
)
grpc_cc_test(
name = "vector_test",
srcs = ["vector_test.cc"],
language = "C++",
deps = [
"//:grpc",
"//test/core/util:gpr_test_util",
],
external_deps = [
"gtest",
],
)

@ -0,0 +1,42 @@
/*
*
* Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "src/core/lib/support/vector.h"
#include <gtest/gtest.h>
#include "test/core/util/test_config.h"
namespace grpc_core {
namespace testing {
TEST(InlinedVectorTest, CreateAndIterate) {
InlinedVector<int, 1> v{1, 2, 3};
int sum = 0;
for (auto i : v) {
sum += i;
}
EXPECT_EQ(6, sum);
}
} // namespace testing
} // namespace grpc_core
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

@ -71,7 +71,7 @@ grpc_cc_test(
grpc_cc_test( grpc_cc_test(
name = "pid_controller_test", name = "pid_controller_test",
srcs = ["pid_controller_test.c"], srcs = ["pid_controller_test.cc"],
language = "C", language = "C",
deps = [ deps = [
"//:gpr", "//:gpr",
@ -79,6 +79,9 @@ grpc_cc_test(
"//test/core/util:gpr_test_util", "//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util", "//test/core/util:grpc_test_util",
], ],
external_deps = [
"gtest",
],
) )
grpc_cc_test( grpc_cc_test(

@ -143,6 +143,7 @@ TEST_P(BdpEstimatorRandomTest, GetEstimateRandomValues) {
INSTANTIATE_TEST_CASE_P(TooManyNames, BdpEstimatorRandomTest, INSTANTIATE_TEST_CASE_P(TooManyNames, BdpEstimatorRandomTest,
::testing::Values(3, 4, 6, 9, 13, 19, 28, 42, 63, 94, ::testing::Values(3, 4, 6, 9, 13, 19, 28, 42, 63, 94,
141, 211, 316, 474, 711)); 141, 211, 316, 474, 711));
} // namespace testing } // namespace testing
} // namespace grpc_core } // namespace grpc_core

@ -43,10 +43,15 @@ void **to_delete = NULL;
size_t num_to_delete = 0; size_t num_to_delete = 0;
size_t cap_to_delete = 0; size_t cap_to_delete = 0;
typedef struct {
bool eof;
bool use_true_binary_metadata;
bool only_intern_key;
} verify_params;
/* verify that the output generated by encoding the stream matches the /* verify that the output generated by encoding the stream matches the
hexstring passed in */ hexstring passed in */
static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof, static void verify(grpc_exec_ctx *exec_ctx, const verify_params params,
bool use_true_binary_metadata, size_t expect_window_used,
const char *expected, size_t nheaders, ...) { const char *expected, size_t nheaders, ...) {
grpc_slice_buffer output; grpc_slice_buffer output;
grpc_slice merged; grpc_slice merged;
@ -66,9 +71,13 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof,
e[i - 1].next = &e[i]; e[i - 1].next = &e[i];
e[i].prev = &e[i - 1]; e[i].prev = &e[i - 1];
} }
grpc_slice value_slice = grpc_slice_from_static_string(value);
if (!params.only_intern_key) {
value_slice = grpc_slice_intern(value_slice);
}
e[i].md = grpc_mdelem_from_slices( e[i].md = grpc_mdelem_from_slices(
exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(key)), exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(key)),
grpc_slice_intern(grpc_slice_from_static_string(value))); value_slice);
} }
e[0].prev = NULL; e[0].prev = NULL;
e[nheaders - 1].next = NULL; e[nheaders - 1].next = NULL;
@ -90,8 +99,8 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof,
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
grpc_encode_header_options hopt = { grpc_encode_header_options hopt = {
.stream_id = 0xdeadbeef, .stream_id = 0xdeadbeef,
.is_eof = eof, .is_eof = params.eof,
.use_true_binary_metadata = use_true_binary_metadata, .use_true_binary_metadata = params.use_true_binary_metadata,
.max_frame_size = 16384, .max_frame_size = 16384,
.stats = &stats, .stats = &stats,
}; };
@ -119,28 +128,27 @@ static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, bool eof,
static void test_basic_headers(grpc_exec_ctx *exec_ctx) { static void test_basic_headers(grpc_exec_ctx *exec_ctx) {
int i; int i;
verify(exec_ctx, 0, false, false, 0, "000005 0104 deadbeef 40 0161 0161", 1, verify_params params = {
"a", "a"); .eof = false, .use_true_binary_metadata = false, .only_intern_key = false,
verify(exec_ctx, 0, false, false, 0, "000001 0104 deadbeef be", 1, "a", "a"); };
verify(exec_ctx, 0, false, false, 0, "000001 0104 deadbeef be", 1, "a", "a"); verify(exec_ctx, params, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
verify(exec_ctx, 0, false, false, 0, "000006 0104 deadbeef be 40 0162 0163", verify(exec_ctx, params, "000001 0104 deadbeef be", 1, "a", "a");
2, "a", "a", "b", "c"); verify(exec_ctx, params, "000001 0104 deadbeef be", 1, "a", "a");
verify(exec_ctx, 0, false, false, 0, "000002 0104 deadbeef bf be", 2, "a", verify(exec_ctx, params, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a",
"a", "b", "c"); "b", "c");
verify(exec_ctx, 0, false, false, 0, "000004 0104 deadbeef 7f 00 0164", 1, verify(exec_ctx, params, "000002 0104 deadbeef bf be", 2, "a", "a", "b", "c");
"a", "d"); verify(exec_ctx, params, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
/* flush out what's there to make a few values look very popular */ /* flush out what's there to make a few values look very popular */
for (i = 0; i < 350; i++) { for (i = 0; i < 350; i++) {
verify(exec_ctx, 0, false, false, 0, "000003 0104 deadbeef c0 bf be", 3, verify(exec_ctx, params, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b",
"a", "a", "b", "c", "a", "d"); "c", "a", "d");
} }
verify(exec_ctx, 0, false, false, 0, "000006 0104 deadbeef c0 00 016b 0176", verify(exec_ctx, params, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a",
2, "a", "a", "k", "v"); "k", "v");
/* this could be 000004 0104 deadbeef 0f 30 0176 also */ /* this could be 000004 0104 deadbeef 0f 30 0176 also */
verify(exec_ctx, 0, false, false, 0, "000004 0104 deadbeef 0f 2f 0176", 1, verify(exec_ctx, params, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
"a", "v");
} }
static void encode_int_to_str(int i, char *p) { static void encode_int_to_str(int i, char *p) {
@ -156,6 +164,10 @@ static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) {
char key[3], value[3]; char key[3], value[3];
char *expect; char *expect;
verify_params params = {
.eof = false, .use_true_binary_metadata = false, .only_intern_key = false,
};
for (i = 0; i < 114; i++) { for (i = 0; i < 114; i++) {
encode_int_to_str(i, key); encode_int_to_str(i, key);
encode_int_to_str(i + 1, value); encode_int_to_str(i + 1, value);
@ -174,27 +186,28 @@ static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) {
} }
if (i > 0) { if (i > 0) {
verify(exec_ctx, 0, false, false, 0, expect, 2, "aa", "ba", key, value); verify(exec_ctx, params, expect, 2, "aa", "ba", key, value);
} else { } else {
verify(exec_ctx, 0, false, false, 0, expect, 1, key, value); verify(exec_ctx, params, expect, 1, key, value);
} }
gpr_free(expect); gpr_free(expect);
} }
/* if the above passes, then we must have just knocked this pair out of the /* if the above passes, then we must have just knocked this pair out of the
decoder stack, and so we'll be forced to re-encode it */ decoder stack, and so we'll be forced to re-encode it */
verify(exec_ctx, 0, false, false, 0, "000007 0104 deadbeef 40 026161 026261", verify(exec_ctx, params, "000007 0104 deadbeef 40 026161 026261", 1, "aa",
1, "aa", "ba"); "ba");
} }
static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx, static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
const char *key, const char *key,
const char *value) { const char *value,
bool use_true_binary) {
grpc_slice_buffer output; grpc_slice_buffer output;
grpc_mdelem elem = grpc_mdelem_from_slices( grpc_mdelem elem = grpc_mdelem_from_slices(
exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(key)), exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(key)),
grpc_slice_intern(grpc_slice_from_static_string(value))); grpc_slice_intern(grpc_slice_from_static_string(value)));
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem); size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, use_true_binary);
size_t initial_table_size = g_compressor.table_size; size_t initial_table_size = g_compressor.table_size;
grpc_linked_mdelem *e = gpr_malloc(sizeof(*e)); grpc_linked_mdelem *e = gpr_malloc(sizeof(*e));
grpc_metadata_batch b; grpc_metadata_batch b;
@ -209,11 +222,12 @@ static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
grpc_transport_one_way_stats stats; grpc_transport_one_way_stats stats;
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
grpc_encode_header_options hopt = {.stream_id = 0xdeadbeef, grpc_encode_header_options hopt = {
.is_eof = false, .stream_id = 0xdeadbeef,
.use_true_binary_metadata = false, .is_eof = false,
.max_frame_size = 16384, .use_true_binary_metadata = use_true_binary,
.stats = &stats}; .max_frame_size = 16384,
.stats = &stats};
grpc_chttp2_encode_header(exec_ctx, &g_compressor, NULL, 0, &b, &hopt, grpc_chttp2_encode_header(exec_ctx, &g_compressor, NULL, 0, &b, &hopt,
&output); &output);
grpc_slice_buffer_destroy_internal(exec_ctx, &output); grpc_slice_buffer_destroy_internal(exec_ctx, &output);
@ -224,8 +238,24 @@ static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
} }
static void test_encode_header_size(grpc_exec_ctx *exec_ctx) { static void test_encode_header_size(grpc_exec_ctx *exec_ctx) {
verify_table_size_change_match_elem_size(exec_ctx, "hello", "world"); verify_table_size_change_match_elem_size(exec_ctx, "hello", "world", false);
verify_table_size_change_match_elem_size(exec_ctx, "hello-bin", "world"); verify_table_size_change_match_elem_size(exec_ctx, "hello-bin", "world",
false);
verify_table_size_change_match_elem_size(exec_ctx, "true-binary-bin",
"I_am_true_binary_value", true);
}
static void test_interned_key_indexed(grpc_exec_ctx *exec_ctx) {
int i;
verify_params params = {
.eof = false, .use_true_binary_metadata = false, .only_intern_key = true,
};
verify(exec_ctx, params, "000009 0104 deadbeef 40 0161 0162 0f2f 0163", 2,
"a", "b", "a", "c");
for (i = 0; i < 10; i++) {
verify(exec_ctx, params, "000008 0104 deadbeef 0f2f 0162 0f2f 0163", 2, "a",
"b", "a", "c");
}
} }
static void run_test(void (*test)(grpc_exec_ctx *exec_ctx), const char *name) { static void run_test(void (*test)(grpc_exec_ctx *exec_ctx), const char *name) {
@ -245,6 +275,7 @@ int main(int argc, char **argv) {
TEST(test_basic_headers); TEST(test_basic_headers);
TEST(test_decode_table_overflow); TEST(test_decode_table_overflow);
TEST(test_encode_header_size); TEST(test_encode_header_size);
TEST(test_interned_key_indexed);
grpc_shutdown(); grpc_shutdown();
for (i = 0; i < num_to_delete; i++) { for (i = 0; i < num_to_delete; i++) {
gpr_free(to_delete[i]); gpr_free(to_delete[i]);

@ -302,7 +302,7 @@ static void verify_ascii_header_size(grpc_exec_ctx *exec_ctx, const char *key,
grpc_mdelem elem = grpc_mdelem_from_slices( grpc_mdelem elem = grpc_mdelem_from_slices(
exec_ctx, maybe_intern(grpc_slice_from_static_string(key), intern_key), exec_ctx, maybe_intern(grpc_slice_from_static_string(key), intern_key),
maybe_intern(grpc_slice_from_static_string(value), intern_value)); maybe_intern(grpc_slice_from_static_string(value), intern_value));
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem); size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false);
size_t expected_size = 32 + strlen(key) + strlen(value); size_t expected_size = 32 + strlen(key) + strlen(value);
GPR_ASSERT(expected_size == elem_size); GPR_ASSERT(expected_size == elem_size);
GRPC_MDELEM_UNREF(exec_ctx, elem); GRPC_MDELEM_UNREF(exec_ctx, elem);
@ -316,7 +316,7 @@ static void verify_binary_header_size(grpc_exec_ctx *exec_ctx, const char *key,
maybe_intern(grpc_slice_from_static_buffer(value, value_len), maybe_intern(grpc_slice_from_static_buffer(value, value_len),
intern_value)); intern_value));
GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem))); GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem)));
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem); size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false);
grpc_slice value_slice = grpc_slice value_slice =
grpc_slice_from_copied_buffer((const char *)value, value_len); grpc_slice_from_copied_buffer((const char *)value, value_len);
grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice); grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);

@ -1,78 +0,0 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "src/core/lib/transport/pid_controller.h"
#include <float.h>
#include <math.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include "src/core/lib/support/string.h"
#include "test/core/util/test_config.h"
static void test_noop(void) {
gpr_log(GPR_INFO, "test_noop");
grpc_pid_controller pid;
grpc_pid_controller_init(
&pid, (grpc_pid_controller_args){.gain_p = 1,
.gain_i = 1,
.gain_d = 1,
.initial_control_value = 1,
.min_control_value = DBL_MIN,
.max_control_value = DBL_MAX,
.integral_range = DBL_MAX});
}
static void test_simple_convergence(double gain_p, double gain_i, double gain_d,
double dt, double set_point, double start) {
gpr_log(GPR_INFO,
"test_simple_convergence(p=%lf, i=%lf, d=%lf); dt=%lf set_point=%lf "
"start=%lf",
gain_p, gain_i, gain_d, dt, set_point, start);
grpc_pid_controller pid;
grpc_pid_controller_init(
&pid, (grpc_pid_controller_args){.gain_p = gain_p,
.gain_i = gain_i,
.gain_d = gain_d,
.initial_control_value = start,
.min_control_value = DBL_MIN,
.max_control_value = DBL_MAX,
.integral_range = DBL_MAX});
for (int i = 0; i < 100000; i++) {
grpc_pid_controller_update(&pid, set_point - grpc_pid_controller_last(&pid),
1);
}
GPR_ASSERT(fabs(set_point - grpc_pid_controller_last(&pid)) < 0.1);
if (gain_i > 0) {
GPR_ASSERT(fabs(pid.error_integral) < 0.1);
}
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_noop();
test_simple_convergence(0.2, 0, 0, 1, 100, 0);
test_simple_convergence(0.2, 0.1, 0, 1, 100, 0);
test_simple_convergence(0.2, 0.1, 0.1, 1, 100, 0);
return 0;
}

@ -0,0 +1,91 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "src/core/lib/transport/pid_controller.h"
#include <float.h>
#include <math.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include <gtest/gtest.h>
#include "src/core/lib/support/string.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
namespace testing {
TEST(PidController, NoOp) {
PidController pid(PidController::Args()
.set_gain_p(1)
.set_gain_i(1)
.set_gain_d(1)
.set_initial_control_value(1));
}
struct SimpleConvergenceTestArgs {
double gain_p;
double gain_i;
double gain_d;
double dt;
double set_point;
double start;
};
std::ostream& operator<<(std::ostream& out, SimpleConvergenceTestArgs args) {
return out << "gain_p:" << args.gain_p << " gain_i:" << args.gain_i
<< " gain_d:" << args.gain_d << " dt:" << args.dt
<< " set_point:" << args.set_point << " start:" << args.start;
}
class SimpleConvergenceTest
: public ::testing::TestWithParam<SimpleConvergenceTestArgs> {};
TEST_P(SimpleConvergenceTest, Converges) {
PidController pid(PidController::Args()
.set_gain_p(GetParam().gain_p)
.set_gain_i(GetParam().gain_i)
.set_gain_d(GetParam().gain_d)
.set_initial_control_value(GetParam().start));
for (int i = 0; i < 100000; i++) {
pid.Update(GetParam().set_point - pid.last_control_value(), GetParam().dt);
}
EXPECT_LT(fabs(GetParam().set_point - pid.last_control_value()), 0.1);
if (GetParam().gain_i > 0) {
EXPECT_LT(fabs(pid.error_integral()), 0.1);
}
}
INSTANTIATE_TEST_CASE_P(
X, SimpleConvergenceTest,
::testing::Values(SimpleConvergenceTestArgs{0.2, 0, 0, 1, 100, 0},
SimpleConvergenceTestArgs{0.2, 0.1, 0, 1, 100, 0},
SimpleConvergenceTestArgs{0.2, 0.1, 0.1, 1, 100, 0}));
} // namespace testing
} // namespace grpc_core
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

@ -34,6 +34,15 @@ extern "C" {
auto &force_library_initialization = Library::get(); auto &force_library_initialization = Library::get();
static grpc_slice MakeSlice(std::vector<uint8_t> bytes) {
grpc_slice s = grpc_slice_malloc(bytes.size());
uint8_t *p = GRPC_SLICE_START_PTR(s);
for (auto b : bytes) {
*p++ = b;
}
return s;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// HPACK encoder // HPACK encoder
// //
@ -52,6 +61,48 @@ static void BM_HpackEncoderInitDestroy(benchmark::State &state) {
} }
BENCHMARK(BM_HpackEncoderInitDestroy); BENCHMARK(BM_HpackEncoderInitDestroy);
static void BM_HpackEncoderEncodeDeadline(benchmark::State &state) {
TrackCounters track_counters;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_millis saved_now = grpc_exec_ctx_now(&exec_ctx);
grpc_metadata_batch b;
grpc_metadata_batch_init(&b);
b.deadline = saved_now + 30 * 1000;
grpc_chttp2_hpack_compressor c;
grpc_chttp2_hpack_compressor_init(&c);
grpc_transport_one_way_stats stats;
memset(&stats, 0, sizeof(stats));
grpc_slice_buffer outbuf;
grpc_slice_buffer_init(&outbuf);
while (state.KeepRunning()) {
grpc_encode_header_options hopt = {
static_cast<uint32_t>(state.iterations()),
true,
false,
(size_t)1024,
&stats,
};
grpc_chttp2_encode_header(&exec_ctx, &c, NULL, 0, &b, &hopt, &outbuf);
grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, &outbuf);
grpc_exec_ctx_flush(&exec_ctx);
}
grpc_metadata_batch_destroy(&exec_ctx, &b);
grpc_chttp2_hpack_compressor_destroy(&exec_ctx, &c);
grpc_slice_buffer_destroy_internal(&exec_ctx, &outbuf);
grpc_exec_ctx_finish(&exec_ctx);
std::ostringstream label;
label << "framing_bytes/iter:" << (static_cast<double>(stats.framing_bytes) /
static_cast<double>(state.iterations()))
<< " header_bytes/iter:" << (static_cast<double>(stats.header_bytes) /
static_cast<double>(state.iterations()));
track_counters.AddLabel(label.str());
track_counters.Finish(state);
}
BENCHMARK(BM_HpackEncoderEncodeDeadline);
template <class Fixture> template <class Fixture>
static void BM_HpackEncoderEncodeHeader(benchmark::State &state) { static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
TrackCounters track_counters; TrackCounters track_counters;
@ -104,7 +155,7 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
static_cast<double>(state.iterations())) static_cast<double>(state.iterations()))
<< " header_bytes/iter:" << (static_cast<double>(stats.header_bytes) / << " header_bytes/iter:" << (static_cast<double>(stats.header_bytes) /
static_cast<double>(state.iterations())); static_cast<double>(state.iterations()));
state.SetLabel(label.str()); track_counters.AddLabel(label.str());
track_counters.Finish(state); track_counters.Finish(state);
} }
@ -220,6 +271,45 @@ class RepresentativeClientInitialMetadata {
} }
}; };
// This fixture reflects how initial metadata are sent by a production client,
// with non-indexed :path and binary headers. The metadata here are the same as
// the corresponding parser benchmark below.
class MoreRepresentativeClientInitialMetadata {
public:
static constexpr bool kEnableTrueBinary = true;
static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
return {
GRPC_MDELEM_SCHEME_HTTP, GRPC_MDELEM_METHOD_POST,
grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_PATH,
grpc_slice_intern(grpc_slice_from_static_string(
"/grpc.test.FooService/BarMethod"))),
grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_AUTHORITY,
grpc_slice_intern(grpc_slice_from_static_string(
"foo.test.google.fr:1234"))),
grpc_mdelem_from_slices(
exec_ctx, GRPC_MDSTR_GRPC_TRACE_BIN,
grpc_slice_from_static_string("\x00\x01\x02\x03\x04\x05\x06\x07\x08"
"\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18"
"\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28"
"\x29\x2a\x2b\x2c\x2d\x2e\x2f"
"\x30")),
grpc_mdelem_from_slices(
exec_ctx, GRPC_MDSTR_GRPC_TAGS_BIN,
grpc_slice_from_static_string("\x00\x01\x02\x03\x04\x05\x06\x07\x08"
"\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13")),
GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP,
GRPC_MDELEM_TE_TRAILERS,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC,
grpc_mdelem_from_slices(
exec_ctx, GRPC_MDSTR_USER_AGENT,
grpc_slice_intern(grpc_slice_from_static_string(
"grpc-c/3.0.0-dev (linux; chttp2; green)")))};
}
};
class RepresentativeServerInitialMetadata { class RepresentativeServerInitialMetadata {
public: public:
static constexpr bool kEnableTrueBinary = true; static constexpr bool kEnableTrueBinary = true;
@ -316,6 +406,9 @@ BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem)
BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
RepresentativeClientInitialMetadata) RepresentativeClientInitialMetadata)
->Args({0, 16384}); ->Args({0, 16384});
BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
MoreRepresentativeClientInitialMetadata)
->Args({0, 16384});
BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
RepresentativeServerInitialMetadata) RepresentativeServerInitialMetadata)
->Args({0, 16384}); ->Args({0, 16384});
@ -359,11 +452,13 @@ static void BM_HpackParserParseHeader(benchmark::State &state) {
p.on_header = UnrefHeader; p.on_header = UnrefHeader;
p.on_header_user_data = nullptr; p.on_header_user_data = nullptr;
for (auto slice : init_slices) { for (auto slice : init_slices) {
grpc_chttp2_hpack_parser_parse(&exec_ctx, &p, slice); GPR_ASSERT(GRPC_ERROR_NONE ==
grpc_chttp2_hpack_parser_parse(&exec_ctx, &p, slice));
} }
while (state.KeepRunning()) { while (state.KeepRunning()) {
for (auto slice : benchmark_slices) { for (auto slice : benchmark_slices) {
grpc_chttp2_hpack_parser_parse(&exec_ctx, &p, slice); GPR_ASSERT(GRPC_ERROR_NONE ==
grpc_chttp2_hpack_parser_parse(&exec_ctx, &p, slice));
} }
grpc_exec_ctx_flush(&exec_ctx); grpc_exec_ctx_flush(&exec_ctx);
} }
@ -376,15 +471,6 @@ static void BM_HpackParserParseHeader(benchmark::State &state) {
namespace hpack_parser_fixtures { namespace hpack_parser_fixtures {
static grpc_slice MakeSlice(std::vector<uint8_t> bytes) {
grpc_slice s = grpc_slice_malloc(bytes.size());
uint8_t *p = GRPC_SLICE_START_PTR(s);
for (auto b : bytes) {
*p++ = b;
}
return s;
}
class EmptyBatch { class EmptyBatch {
public: public:
static std::vector<grpc_slice> GetInitSlices() { return {}; } static std::vector<grpc_slice> GetInitSlices() { return {}; }
@ -572,6 +658,54 @@ class RepresentativeClientInitialMetadata {
} }
}; };
// This fixture reflects how initial metadata are sent by a production client,
// with non-indexed :path and binary headers. The metadata here are the same as
// the corresponding encoder benchmark above.
class MoreRepresentativeClientInitialMetadata {
public:
static std::vector<grpc_slice> GetInitSlices() {
return {MakeSlice(
{0x40, 0x07, ':', 's', 'c', 'h', 'e', 'm', 'e', 0x04, 'h', 't',
't', 'p', 0x40, 0x07, ':', 'm', 'e', 't', 'h', 'o', 'd', 0x04,
'P', 'O', 'S', 'T', 0x40, 0x05, ':', 'p', 'a', 't', 'h', 0x1f,
'/', 'g', 'r', 'p', 'c', '.', 't', 'e', 's', 't', '.', 'F',
'o', 'o', 'S', 'e', 'r', 'v', 'i', 'c', 'e', '/', 'B', 'a',
'r', 'M', 'e', 't', 'h', 'o', 'd', 0x40, 0x0a, ':', 'a', 'u',
't', 'h', 'o', 'r', 'i', 't', 'y', 0x09, 'l', 'o', 'c', 'a',
'l', 'h', 'o', 's', 't', 0x40, 0x0e, 'g', 'r', 'p', 'c', '-',
't', 'r', 'a', 'c', 'e', '-', 'b', 'i', 'n', 0x31, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x40,
0x0d, 'g', 'r', 'p', 'c', '-', 't', 'a', 'g', 's', '-', 'b',
'i', 'n', 0x14, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x40,
0x0c, 'c', 'o', 'n', 't', 'e', 'n', 't', '-', 't', 'y', 'p',
'e', 0x10, 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o',
'n', '/', 'g', 'r', 'p', 'c', 0x40, 0x14, 'g', 'r', 'p', 'c',
'-', 'a', 'c', 'c', 'e', 'p', 't', '-', 'e', 'n', 'c', 'o',
'd', 'i', 'n', 'g', 0x15, 'i', 'd', 'e', 'n', 't', 'i', 't',
'y', ',', 'd', 'e', 'f', 'l', 'a', 't', 'e', ',', 'g', 'z',
'i', 'p', 0x40, 0x02, 't', 'e', 0x08, 't', 'r', 'a', 'i', 'l',
'e', 'r', 's', 0x40, 0x0a, 'u', 's', 'e', 'r', '-', 'a', 'g',
'e', 'n', 't', 0x22, 'b', 'a', 'd', '-', 'c', 'l', 'i', 'e',
'n', 't', ' ', 'g', 'r', 'p', 'c', '-', 'c', '/', '0', '.',
'1', '2', '.', '0', '.', '0', ' ', '(', 'l', 'i', 'n', 'u',
'x', ')'})};
}
static std::vector<grpc_slice> GetBenchmarkSlices() {
return {MakeSlice(
{0xc7, 0xc6, 0xc5, 0xc4, 0x7f, 0x04, 0x31, 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x7f, 0x03, 0x14, 0x00,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0xc1, 0xc0, 0xbf, 0xbe})};
}
};
class RepresentativeServerInitialMetadata { class RepresentativeServerInitialMetadata {
public: public:
static std::vector<grpc_slice> GetInitSlices() { static std::vector<grpc_slice> GetInitSlices() {
@ -645,6 +779,8 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<31, true>);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<100, true>); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem<100, true>);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeClientInitialMetadata); RepresentativeClientInitialMetadata);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
MoreRepresentativeClientInitialMetadata);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeServerInitialMetadata); RepresentativeServerInitialMetadata);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,

@ -20,6 +20,9 @@
void TrackCounters::Finish(benchmark::State &state) { void TrackCounters::Finish(benchmark::State &state) {
std::ostringstream out; std::ostringstream out;
for (const auto &l : labels_) {
out << l << ' ';
}
AddToLabel(out, state); AddToLabel(out, state);
std::string label = out.str(); std::string label = out.str();
if (label.length() && label[0] == ' ') { if (label.length() && label[0] == ' ') {
@ -28,6 +31,10 @@ void TrackCounters::Finish(benchmark::State &state) {
state.SetLabel(label.c_str()); state.SetLabel(label.c_str());
} }
void TrackCounters::AddLabel(const grpc::string &label) {
labels_.push_back(label);
}
void TrackCounters::AddToLabel(std::ostream &out, benchmark::State &state) { void TrackCounters::AddToLabel(std::ostream &out, benchmark::State &state) {
grpc_stats_data stats_end; grpc_stats_data stats_end;
grpc_stats_collect(&stats_end); grpc_stats_collect(&stats_end);

@ -20,6 +20,7 @@
#define TEST_CPP_MICROBENCHMARKS_COUNTERS_H #define TEST_CPP_MICROBENCHMARKS_COUNTERS_H
#include <sstream> #include <sstream>
#include <vector>
extern "C" { extern "C" {
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
@ -65,10 +66,12 @@ class TrackCounters {
public: public:
TrackCounters() { grpc_stats_collect(&stats_begin_); } TrackCounters() { grpc_stats_collect(&stats_begin_); }
virtual void Finish(benchmark::State& state); virtual void Finish(benchmark::State& state);
virtual void AddLabel(const grpc::string& label);
virtual void AddToLabel(std::ostream& out, benchmark::State& state); virtual void AddToLabel(std::ostream& out, benchmark::State& state);
private: private:
grpc_stats_data stats_begin_; grpc_stats_data stats_begin_;
std::vector<grpc::string> labels_;
#ifdef GPR_LOW_LEVEL_COUNTERS #ifdef GPR_LOW_LEVEL_COUNTERS
const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks); const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&gpr_mu_locks);
const size_t atm_cas_at_start_ = const size_t atm_cas_at_start_ =

@ -0,0 +1 @@
Subproject commit cc4bed2d74f7c8717e31f9579214ab52a9c9c610

@ -17,17 +17,18 @@
set -e set -e
mkdir -p /var/local/git mkdir -p /var/local/git
git clone /var/local/jenkins/grpc /var/local/git/grpc git clone /var/local/jenkins/grpc-node /var/local/git/grpc-node
# clone gRPC submodules, use data from locally cloned submodules where possible # clone gRPC submodules, use data from locally cloned submodules where possible
(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ (cd /var/local/jenkins/grpc-node/ && git submodule foreach 'cd /var/local/git/grpc-node \
&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \ && git submodule update --init --recursive --reference /var/local/jenkins/grpc-node/${name} \
${name}') ${name}')
# copy service account keys if available # copy service account keys if available
cp -r /var/local/jenkins/service_account $HOME || true cp -r /var/local/jenkins/service_account $HOME || true
cd /var/local/git/grpc cd /var/local/git/grpc-node
# build Node interop client & server # build Node interop client & server
npm install -g node-gyp npm install -g node-gyp gulp
npm install --unsafe-perm --build-from-source npm install
gulp setup

@ -1041,6 +1041,7 @@ src/core/lib/support/string.h \
src/core/lib/support/string_windows.h \ src/core/lib/support/string_windows.h \
src/core/lib/support/time_precise.h \ src/core/lib/support/time_precise.h \
src/core/lib/support/tmpfile.h \ src/core/lib/support/tmpfile.h \
src/core/lib/support/vector.h \
src/core/lib/surface/alarm_internal.h \ src/core/lib/surface/alarm_internal.h \
src/core/lib/surface/api_trace.h \ src/core/lib/surface/api_trace.h \
src/core/lib/surface/call.h \ src/core/lib/surface/call.h \

@ -1354,6 +1354,7 @@ src/core/lib/support/tmpfile.h \
src/core/lib/support/tmpfile_msys.cc \ src/core/lib/support/tmpfile_msys.cc \
src/core/lib/support/tmpfile_posix.cc \ src/core/lib/support/tmpfile_posix.cc \
src/core/lib/support/tmpfile_windows.cc \ src/core/lib/support/tmpfile_windows.cc \
src/core/lib/support/vector.h \
src/core/lib/support/wrap_memcpy.cc \ src/core/lib/support/wrap_memcpy.cc \
src/core/lib/surface/README.md \ src/core/lib/surface/README.md \
src/core/lib/surface/alarm.cc \ src/core/lib/surface/alarm.cc \

@ -26,7 +26,7 @@ mkdir -p reports
echo '<html><head></head><body>' > reports/kokoro_index.html echo '<html><head></head><body>' > reports/kokoro_index.html
echo '<h1>'${KOKORO_JOB_NAME}', build '#${KOKORO_BUILD_NUMBER}'</h1>' >> reports/kokoro_index.html echo '<h1>'${KOKORO_JOB_NAME}', build '#${KOKORO_BUILD_NUMBER}'</h1>' >> reports/kokoro_index.html
echo '<h2><a href="https://kokoro.corp.google.com/job/'${KOKORO_JOB_PATH}'/'${KOKORO_BUILD_NUMBER}'/">Kokoro build dashboard (internal only)</a></h2>' >> reports/kokoro_index.html echo '<h2><a href="https://kokoro2.corp.google.com/job/'${KOKORO_JOB_PATH}'/'${KOKORO_BUILD_NUMBER}'/">Kokoro build dashboard (internal only)</a></h2>' >> reports/kokoro_index.html
echo '<h2><a href="https://sponge.corp.google.com/invocation?id='${KOKORO_BUILD_ID}'&searchFor=">Test result dashboard (internal only)</a></h2>' >> reports/kokoro_index.html echo '<h2><a href="https://sponge.corp.google.com/invocation?id='${KOKORO_BUILD_ID}'&searchFor=">Test result dashboard (internal only)</a></h2>' >> reports/kokoro_index.html
echo '<h2><a href="test_report.html">HTML test report (Not available yet)</a></h2>' >> reports/kokoro_index.html echo '<h2><a href="test_report.html">HTML test report (Not available yet)</a></h2>' >> reports/kokoro_index.html
echo '<h2><a href="test_log.txt">Test log (Not available yet)</a></h2>' >> reports/kokoro_index.html echo '<h2><a href="test_log.txt">Test log (Not available yet)</a></h2>' >> reports/kokoro_index.html

@ -26,6 +26,7 @@ git submodule update --init
# Set up gRPC-Go and gRPC-Java to test # Set up gRPC-Go and gRPC-Java to test
git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go
git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java
git clone --recursive https://github.com/grpc/grpc-node ./../grpc-node
# Download json file. # Download json file.
mkdir ~/service_account mkdir ~/service_account

@ -30,6 +30,7 @@ brew install md5sha1sum
# Set up gRPC-Go and gRPC-Java to test # Set up gRPC-Go and gRPC-Java to test
git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go
git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java
git clone --recursive https://github.com/grpc/grpc-node ./../grpc-node
# Set up Docker for Mac # Set up Docker for Mac
docker-machine create -d virtualbox --virtualbox-share-folder "/Users/kbuilder/workspace:" default docker-machine create -d virtualbox --virtualbox-share-folder "/Users/kbuilder/workspace:" default

@ -174,7 +174,7 @@ def build_all_images_for_release(lang, release):
# If we not using current tree or the sibling for grpc stack, do checkout. # If we not using current tree or the sibling for grpc stack, do checkout.
if args.git_checkout: if args.git_checkout:
stack_base = checkout_grpc_stack(lang, release) stack_base = checkout_grpc_stack(lang, release)
var ={'go': 'GRPC_GO_ROOT', 'java': 'GRPC_JAVA_ROOT'}.get(lang, 'GRPC_ROOT') var ={'go': 'GRPC_GO_ROOT', 'java': 'GRPC_JAVA_ROOT', 'node': 'GRPC_NODE_ROOT'}.get(lang, 'GRPC_ROOT')
env[var] = stack_base env[var] = stack_base
for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]:

@ -48,6 +48,14 @@ else
echo "WARNING: grpc-go not found, it won't be mounted to the docker container." echo "WARNING: grpc-go not found, it won't be mounted to the docker container."
fi fi
echo "GRPC_NODE_ROOT: ${GRPC_NODE_ROOT:=$(cd ../grpc-node && pwd)}"
if [ -n "$GRPC_NODE_ROOT" ]
then
MOUNT_ARGS+=" -v $GRPC_NODE_ROOT:/var/local/jenkins/grpc-node:ro"
else
echo "WARNING: grpc-node not found, it won't be mounted to the docker container."
fi
mkdir -p /tmp/ccache mkdir -p /tmp/ccache
# Mount service account dir if available. # Mount service account dir if available.

@ -2437,23 +2437,6 @@
"third_party": false, "third_party": false,
"type": "target" "type": "target"
}, },
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "transport_pid_controller_test",
"src": [
"test/core/transport/pid_controller_test.c"
],
"third_party": false,
"type": "target"
},
{ {
"deps": [ "deps": [
"gpr", "gpr",
@ -4242,6 +4225,44 @@
"third_party": false, "third_party": false,
"type": "target" "type": "target"
}, },
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test_util",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c++",
"name": "transport_pid_controller_test",
"src": [
"test/core/transport/pid_controller_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c++",
"name": "vector_test",
"src": [
"test/core/support/vector_test.cc"
],
"third_party": false,
"type": "target"
},
{ {
"deps": [ "deps": [
"gpr", "gpr",
@ -8249,6 +8270,7 @@
"src/core/lib/slice/slice_hash_table.h", "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h", "src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h", "src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/support/vector.h",
"src/core/lib/surface/alarm_internal.h", "src/core/lib/surface/alarm_internal.h",
"src/core/lib/surface/api_trace.h", "src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h", "src/core/lib/surface/call.h",
@ -8384,6 +8406,7 @@
"src/core/lib/slice/slice_hash_table.h", "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h", "src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h", "src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/support/vector.h",
"src/core/lib/surface/alarm_internal.h", "src/core/lib/surface/alarm_internal.h",
"src/core/lib/surface/api_trace.h", "src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h", "src/core/lib/surface/call.h",

@ -2867,31 +2867,7 @@
"posix", "posix",
"windows" "windows"
], ],
"uses_polling": false "uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "transport_pid_controller_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
}, },
{ {
"args": [], "args": [],
@ -4361,7 +4337,9 @@
"windows" "windows"
], ],
"cpu_cost": 1.0, "cpu_cost": 1.0,
"exclude_configs": [], "exclude_configs": [
"tsan"
],
"exclude_iomgrs": [], "exclude_iomgrs": [],
"flaky": false, "flaky": false,
"gtest": true, "gtest": true,
@ -4373,6 +4351,7 @@
"posix", "posix",
"windows" "windows"
], ],
"timeout_seconds": 1200,
"uses_polling": false "uses_polling": false
}, },
{ {
@ -4470,6 +4449,54 @@
"timeout_seconds": 1200, "timeout_seconds": 1200,
"uses_polling": true "uses_polling": true
}, },
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c++",
"name": "transport_pid_controller_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "vector_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{ {
"args": [], "args": [],
"benchmark": false, "benchmark": false,

@ -78,7 +78,7 @@ _WHITELIST_DICT = {
'^src/python/': [_PYTHON_TEST_SUITE], '^src/python/': [_PYTHON_TEST_SUITE],
'^src/ruby/': [_RUBY_TEST_SUITE], '^src/ruby/': [_RUBY_TEST_SUITE],
'^templates/': [], '^templates/': [],
'^test/core/': [_CORE_TEST_SUITE], '^test/core/': [_CORE_TEST_SUITE, _CPP_TEST_SUITE],
'^test/cpp/': [_CPP_TEST_SUITE], '^test/cpp/': [_CPP_TEST_SUITE],
'^test/distrib/cpp/': [_CPP_TEST_SUITE], '^test/distrib/cpp/': [_CPP_TEST_SUITE],
'^test/distrib/csharp/': [_CSHARP_TEST_SUITE], '^test/distrib/csharp/': [_CSHARP_TEST_SUITE],

@ -313,20 +313,20 @@ class Http2Client:
class NodeLanguage: class NodeLanguage:
def __init__(self): def __init__(self):
self.client_cwd = None self.client_cwd = '../grpc-node'
self.server_cwd = None self.server_cwd = '../grpc-node'
self.safename = str(self) self.safename = str(self)
def client_cmd(self, args): def client_cmd(self, args):
return ['tools/run_tests/interop/with_nvm.sh', return ['packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh',
'node', 'src/node/interop/interop_client.js'] + args 'node', 'test/interop/interop_client.js'] + args
def cloud_to_prod_env(self): def cloud_to_prod_env(self):
return {} return {}
def server_cmd(self, args): def server_cmd(self, args):
return ['tools/run_tests/interop/with_nvm.sh', return ['packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh',
'node', 'src/node/interop/interop_server.js'] + args 'node', 'test/interop/interop_server.js'] + args
def global_env(self): def global_env(self):
return {} return {}

@ -340,12 +340,12 @@ class CLanguage(object):
with open(os.devnull, 'w') as fnull: with open(os.devnull, 'w') as fnull:
tests = subprocess.check_output([binary, '--benchmark_list_tests'], tests = subprocess.check_output([binary, '--benchmark_list_tests'],
stderr=fnull) stderr=fnull)
base = None
for line in tests.split('\n'): for line in tests.split('\n'):
test = line.strip() test = line.strip()
if not test: continue
cmdline = [binary, '--benchmark_filter=%s$' % test] + target['args'] cmdline = [binary, '--benchmark_filter=%s$' % test] + target['args']
out.append(self.config.job_spec(cmdline, out.append(self.config.job_spec(cmdline,
shortname='%s:%s %s' % (binary, test, shortname_ext), shortname='%s %s' % (' '.join(cmdline), shortname_ext),
cpu_cost=cpu_cost, cpu_cost=cpu_cost,
timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling, timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling,
environ=env)) environ=env))
@ -371,7 +371,7 @@ class CLanguage(object):
out.append(self.config.job_spec(cmdline, out.append(self.config.job_spec(cmdline,
shortname='%s %s' % (' '.join(cmdline), shortname_ext), shortname='%s %s' % (' '.join(cmdline), shortname_ext),
cpu_cost=cpu_cost, cpu_cost=cpu_cost,
timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling, timeout_seconds=target.get('timeout_seconds', _DEFAULT_TIMEOUT_SECONDS) * timeout_scaling,
environ=env)) environ=env))
else: else:
cmdline = [binary] + target['args'] cmdline = [binary] + target['args']

@ -36,6 +36,7 @@ def get_target(name):
assert False, 'no target %s' % name assert False, 'no target %s' % name
def target_has_header(target, name): def target_has_header(target, name):
if name.startswith('absl/'): return True
# print target['name'], name # print target['name'], name
if name in target['headers']: if name in target['headers']:
return True return True

@ -35,6 +35,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules
cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0) 3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty 73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty
cc4bed2d74f7c8717e31f9579214ab52a9c9c610 third_party/abseil-cpp
EOF EOF
diff -u $submodules $want_submodules diff -u $submodules $want_submodules

@ -81,7 +81,8 @@ class TestFilteringTest(unittest.TestCase):
self.test_filtering(['src/core/foo.bar'], [_LIST_OF_LANGUAGE_LABELS]) self.test_filtering(['src/core/foo.bar'], [_LIST_OF_LANGUAGE_LABELS])
# Testing individual languages # Testing individual languages
self.test_filtering(['test/core/foo.bar'], [label for label in _LIST_OF_LANGUAGE_LABELS if label not in self.test_filtering(['test/core/foo.bar'], [label for label in _LIST_OF_LANGUAGE_LABELS if label not in
filter_pull_request_tests._CORE_TEST_SUITE.labels]) filter_pull_request_tests._CORE_TEST_SUITE.labels +
filter_pull_request_tests._CPP_TEST_SUITE.labels])
self.test_filtering(['src/cpp/foo.bar'], [label for label in _LIST_OF_LANGUAGE_LABELS if label not in self.test_filtering(['src/cpp/foo.bar'], [label for label in _LIST_OF_LANGUAGE_LABELS if label not in
filter_pull_request_tests._CPP_TEST_SUITE.labels]) filter_pull_request_tests._CPP_TEST_SUITE.labels])
self.test_filtering(['src/csharp/foo.bar'], [label for label in _LIST_OF_LANGUAGE_LABELS if label not in self.test_filtering(['src/csharp/foo.bar'], [label for label in _LIST_OF_LANGUAGE_LABELS if label not in

Loading…
Cancel
Save