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

pull/19778/head
Matthew Stevenson 5 years ago
commit 0867a350f9
  1. 30
      CMakeLists.txt
  2. 112
      Makefile
  3. 3
      WORKSPACE
  4. 1
      bazel/python_rules.bzl
  5. 3
      bazel/test/python_test_repo/WORKSPACE
  6. 6
      build.yaml
  7. 53
      examples/objective-c/helloworld/README.md
  8. 16
      examples/python/data_transmission/README.cn.md
  9. 16
      examples/python/data_transmission/README.en.md
  10. 28
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  11. 8
      src/core/lib/iomgr/endpoint_cfstream.cc
  12. 62
      src/core/lib/iomgr/resource_quota.cc
  13. 22
      src/core/lib/iomgr/resource_quota.h
  14. 8
      src/core/lib/iomgr/tcp_custom.cc
  15. 19
      src/core/lib/iomgr/tcp_posix.cc
  16. 49
      src/objective-c/tests/InteropTests/InteropTests.h
  17. 41
      src/objective-c/tests/MacTests/StressTests.h
  18. 27
      src/objective-c/tests/PerfTests/PerfTests.h
  19. 327
      src/objective-c/tests/PerfTests/PerfTests.m
  20. 33
      src/objective-c/tests/PerfTests/PerfTestsBlockCallbacks.h
  21. 80
      src/objective-c/tests/PerfTests/PerfTestsBlockCallbacks.m
  22. 74
      src/objective-c/tests/PerfTests/PerfTestsCFStreamCleartext.m
  23. 80
      src/objective-c/tests/PerfTests/PerfTestsCFStreamSSL.m
  24. 63
      src/objective-c/tests/PerfTests/PerfTestsCronet.m
  25. 74
      src/objective-c/tests/PerfTests/PerfTestsNoCFStreamCleartext.m
  26. 80
      src/objective-c/tests/PerfTests/PerfTestsNoCFStreamSSL.m
  27. 8
      src/objective-c/tests/Podfile
  28. 65
      src/objective-c/tests/TestBase.h
  29. 50
      src/objective-c/tests/TestBase.m
  30. 245
      src/objective-c/tests/Tests.xcodeproj/project.pbxproj
  31. 95
      src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/PerfTests.xcscheme
  32. 2
      src/proto/grpc/testing/xds/BUILD
  33. 0
      src/proto/grpc/testing/xds/eds_for_test.proto
  34. 2
      src/proto/grpc/testing/xds/lrs_for_test.proto
  35. 0
      src/proto/grpc/testing/xds/orca_load_report_for_test.proto
  36. 1
      test/core/end2end/generate_tests.bzl
  37. 62
      test/core/iomgr/resource_quota_test.cc
  38. 6
      test/cpp/end2end/BUILD
  39. 91
      test/cpp/end2end/client_lb_end2end_test.cc
  40. 4
      test/cpp/end2end/xds_end2end_test.cc
  41. 2
      tools/internal_ci/linux/grpc_e2e_performance_singlevm.sh
  42. 6
      tools/internal_ci/linux/grpc_full_performance_master.sh
  43. 6
      tools/internal_ci/linux/grpc_full_performance_release.sh
  44. 11
      tools/run_tests/run_performance_tests.py
  45. 6
      tools/run_tests/run_tests_matrix.py

@ -12383,17 +12383,17 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(client_lb_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/orca_load_report_for_test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/orca_load_report_for_test.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.h
test/cpp/end2end/client_lb_end2end_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
protobuf_generate_grpc_cpp(
src/proto/grpc/lb/v2/orca_load_report_for_test.proto
src/proto/grpc/testing/xds/orca_load_report_for_test.proto
)
target_include_directories(client_lb_end2end_test
@ -16824,24 +16824,24 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(xds_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/eds_for_test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/eds_for_test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/lrs_for_test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/lrs_for_test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h
test/cpp/end2end/xds_end2end_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
protobuf_generate_grpc_cpp(
src/proto/grpc/lb/v2/eds_for_test.proto
src/proto/grpc/testing/xds/eds_for_test.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/lb/v2/lrs_for_test.proto
src/proto/grpc/testing/xds/lrs_for_test.proto
)
target_include_directories(xds_end2end_test

@ -2714,54 +2714,6 @@ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v1/lo
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc: src/proto/grpc/lb/v2/eds_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.cc: src/proto/grpc/lb/v2/eds_for_test.proto $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.pb.cc: src/proto/grpc/lb/v2/lrs_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.cc: src/proto/grpc/lb/v2/lrs_for_test.proto $(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.cc
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.cc: src/proto/grpc/lb/v2/orca_load_report_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.grpc.pb.cc: src/proto/grpc/lb/v2/orca_load_report_for_test.proto $(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error
@ -3036,6 +2988,54 @@ $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: src/proto/grpc/testi
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc: src/proto/grpc/testing/xds/eds_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/eds_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc: src/proto/grpc/testing/xds/lrs_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/lrs_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc: src/proto/grpc/testing/xds/orca_load_report_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/orca_load_report_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
ifeq ($(CONFIG),stapprof)
src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
@ -15744,7 +15744,7 @@ endif
CLIENT_LB_END2END_TEST_SRC = \
$(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc \
test/cpp/end2end/client_lb_end2end_test.cc \
CLIENT_LB_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLIENT_LB_END2END_TEST_SRC))))
@ -15776,7 +15776,7 @@ endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v2/orca_load_report_for_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/xds/orca_load_report_for_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
@ -15787,7 +15787,7 @@ ifneq ($(NO_DEPS),true)
-include $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/orca_load_report_for_test.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc
CODEGEN_TEST_FULL_SRC = \
@ -20086,8 +20086,8 @@ endif
XDS_END2END_TEST_SRC = \
$(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc \
test/cpp/end2end/xds_end2end_test.cc \
XDS_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(XDS_END2END_TEST_SRC))))
@ -20119,9 +20119,9 @@ endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v2/eds_for_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/xds/eds_for_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v2/lrs_for_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/xds/lrs_for_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
@ -20132,7 +20132,7 @@ ifneq ($(NO_DEPS),true)
-include $(XDS_END2END_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/eds_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.pb.cc $(GENDIR)/src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc
PUBLIC_HEADERS_MUST_BE_C89_SRC = \

@ -51,6 +51,9 @@ load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
pip_repositories()
pip_install()
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()

@ -5,7 +5,6 @@ load(
"get_include_protoc_args",
"get_plugin_args",
"get_proto_root",
"proto_path_to_generated_filename",
"protos_from_context",
"includes_from_deps",
"get_proto_arguments",

@ -6,6 +6,9 @@ local_repository(
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
# TODO(https://github.com/grpc/grpc/issues/19835): Remove.
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()

@ -4751,7 +4751,7 @@ targets:
build: test
language: c++
src:
- src/proto/grpc/lb/v2/orca_load_report_for_test.proto
- src/proto/grpc/testing/xds/orca_load_report_for_test.proto
- test/cpp/end2end/client_lb_end2end_test.cc
deps:
- grpc++_test_util
@ -6035,8 +6035,8 @@ targets:
build: test
language: c++
src:
- src/proto/grpc/lb/v2/eds_for_test.proto
- src/proto/grpc/lb/v2/lrs_for_test.proto
- src/proto/grpc/testing/xds/eds_for_test.proto
- src/proto/grpc/testing/xds/lrs_for_test.proto
- test/cpp/end2end/xds_end2end_test.cc
deps:
- grpc++_test_util

@ -1,12 +1,18 @@
# gRPC in 3 minutes (Objective-C)
There are currently two ways to build projects with the gRPC Objective-C library:
* Cocoapods & Xcode
* Bazel (experimental)
## Cocoapods
## Installation
To run this example you should have [Cocoapods](https://cocoapods.org/#install) installed, as well
as the relevant tools to generate the client library code (and a server in another language, for
testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc).
## Hello Objective-C gRPC!
### Hello Objective-C gRPC!
Here's how to build and run the Objective-C implementation of the [Hello World](../../protos/helloworld.proto)
example used in [Getting started](https://github.com/grpc/grpc/tree/master/examples).
@ -27,7 +33,7 @@ Change your current directory to `examples/objective-c/helloworld`
$ cd examples/objective-c/helloworld
```
### Try it!
#### Try it!
To try the sample app, we need a gRPC server running locally. Let's compile and run, for example,
the C++ server in this repository:
@ -53,6 +59,49 @@ code in `main.m` and see the results in XCode's log console.
The code sends a `HLWHelloRequest` containing the string "Objective-C" to a local server. The server
responds with a `HLWHelloResponse`, which contains a string that is then output to the log.
## Bazel
### Installation
To run the examples in Bazel, you should have [Bazel](https://docs.bazel.build/versions/master/install-os-x.html) installed.
### Hello Objective-C gRPC!
Here's how to build and run the Objective-C implementation of the [Hello World](helloworld) example.
The code for the Hello World example and others live in the `examples` directory. Clone this repository to your local machine by running the following commands:
```shell
$ git clone --recursive https://github.com/grpc/grpc
```
Next, change your directory to `examples/objective-c`
```shell
$ cd grpc/examples/objective-c
```
Now build the Hello World project:
```shell
$ bazel build :HelloWorld
```
#### Try it!
To run the Hello World sample properly, we need a local server. Let's compile and run the corresponding C++ server:
```shell
$ bazel run //examples:greeter_server
```
To run the sample, you need to know the available simulator runtimes in your machine. You could either list the available runtimes yourself by running:
```shell
$ xcrun simctl list
```
Or just try running the app and it will let you know what is available in the error messages:
```shell
$ bazel run :HelloWorld
```
Note that running this command will build the project even if it is not built beforehand.
Finally, launch the app with one of the available runtimes:
```shell
$ bazel run :HelloWorld --ios_simulator_version='<runtime>' --ios_sumlator_device='<device>'
```
## Tutorial
You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://grpc.io/docs/tutorials/basic/objective-c.html).

@ -6,31 +6,31 @@
在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应
`client.py - line:14 - simple_method`
`client.py: simple_method`
`server.py - line:17 - SimpleMethod`
`server.py: SimpleMethod`
- #### 客户端流模式
在一次调用中, 客户端可以多次向服务器传输数据, 但是服务器只能返回一次响应
`clien.py - line:27 - client_streaming_method `
`client.py: client_streaming_method `
`server.py - line:28 - ClientStreamingMethod`
`server.py: ClientStreamingMethod`
- #### 服务端流模式
在一次调用中, 客户端只能向服务器传输一次请求数据, 但是服务器可以多次返回响应
`clien.py - line:48 - server_streaming_method`
`client.py: server_streaming_method`
`server.py - line:41 - ServerStreamingMethod`
`server.py: ServerStreamingMethod`
- #### 双向流模式
在一次调用中, 客户端和服务器都可以向对方多次收发数据
`client.py - line:63 - bidirectional_streaming_method`
`client.py: bidirectional_streaming_method`
`server.py - line:59 - BidirectionalStreamingMethod`
`server.py: BidirectionalStreamingMethod`

@ -6,32 +6,32 @@ Four ways of data transmission when gRPC is used in Python. [Offical Guide](<ht
In a single call, the client can only send request once, and the server can only respond once.
`client.py - line:14 - simple_method`
`client.py: simple_method`
`server.py - line:17 - SimpleMethod`
`server.py: SimpleMethod`
- #### stream-unary
In a single call, the client can transfer data to the server an arbitrary number of times, but the server can only return a response once.
`clien.py - line:27 - client_streaming_method`
`client.py: client_streaming_method`
`server.py - line:28 - ClientStreamingMethod`
`server.py: ClientStreamingMethod`
- #### unary-stream
In a single call, the client can only transmit data to the server at one time, but the server can return the response many times.
`clien.py - line:48 - server_streaming_method`
`client.py: server_streaming_method`
`server.py - line:41 - ServerStreamingMethod`
`server.py: ServerStreamingMethod`
- #### stream-stream
In a single call, both client and server can send and receive data
to each other multiple times.
`client.py - line:63 - bidirectional_streaming_method`
`client.py: bidirectional_streaming_method`
`server.py - line:59 - BidirectionalStreamingMethod`
`server.py: BidirectionalStreamingMethod`

@ -88,14 +88,21 @@ class RoundRobin : public LoadBalancingPolicy {
return last_connectivity_state_;
}
bool seen_failure_since_ready() const { return seen_failure_since_ready_; }
// Performs connectivity state updates that need to be done both when we
// first start watching and when a watcher notification is received.
void UpdateConnectivityStateLocked(
grpc_connectivity_state connectivity_state);
private:
// Performs connectivity state updates that need to be done only
// after we have started watching.
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state) override;
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
bool seen_failure_since_ready_ = false;
};
// A list of subchannels.
@ -375,8 +382,25 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
grpc_connectivity_state_name(last_connectivity_state_),
grpc_connectivity_state_name(connectivity_state));
}
subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
connectivity_state);
// Decide what state to report for aggregation purposes.
// If we haven't seen a failure since the last time we were in state
// READY, then we report the state change as-is. However, once we do see
// a failure, we report TRANSIENT_FAILURE and do not report any subsequent
// state changes until we go back into state READY.
if (!seen_failure_since_ready_) {
if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
seen_failure_since_ready_ = true;
}
subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
connectivity_state);
} else {
if (connectivity_state == GRPC_CHANNEL_READY) {
seen_failure_since_ready_ = false;
subchannel_list()->UpdateStateCountersLocked(
GRPC_CHANNEL_TRANSIENT_FAILURE, connectivity_state);
}
}
// Record last seen connectivity state.
last_connectivity_state_ = connectivity_state;
}

@ -261,10 +261,12 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices,
ep_impl->read_cb = cb;
ep_impl->read_slices = slices;
grpc_slice_buffer_reset_and_unref_internal(slices);
grpc_resource_user_alloc_slices(&ep_impl->slice_allocator,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
ep_impl->read_slices);
EP_REF(ep_impl, "read");
if (grpc_resource_user_alloc_slices(&ep_impl->slice_allocator,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
ep_impl->read_slices)) {
ep_impl->stream_sync->NotifyOnRead(&ep_impl->read_action);
}
}
static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices,

@ -583,16 +583,19 @@ static void ru_destroy(void* ru, grpc_error* error) {
gpr_free(resource_user);
}
static void ru_alloc_slices(
grpc_resource_user_slice_allocator* slice_allocator) {
for (size_t i = 0; i < slice_allocator->count; i++) {
grpc_slice_buffer_add_indexed(
slice_allocator->dest, ru_slice_create(slice_allocator->resource_user,
slice_allocator->length));
}
}
static void ru_allocated_slices(void* arg, grpc_error* error) {
grpc_resource_user_slice_allocator* slice_allocator =
static_cast<grpc_resource_user_slice_allocator*>(arg);
if (error == GRPC_ERROR_NONE) {
for (size_t i = 0; i < slice_allocator->count; i++) {
grpc_slice_buffer_add_indexed(
slice_allocator->dest, ru_slice_create(slice_allocator->resource_user,
slice_allocator->length));
}
}
if (error == GRPC_ERROR_NONE) ru_alloc_slices(slice_allocator);
GRPC_CLOSURE_RUN(&slice_allocator->on_done, GRPC_ERROR_REF(error));
}
@ -880,7 +883,7 @@ void grpc_resource_user_free_threads(grpc_resource_user* resource_user,
gpr_mu_unlock(&resource_user->resource_quota->thread_count_mu);
}
static void resource_user_alloc_locked(grpc_resource_user* resource_user,
static bool resource_user_alloc_locked(grpc_resource_user* resource_user,
size_t size,
grpc_closure* optional_on_done) {
ru_ref_by(resource_user, static_cast<gpr_atm>(size));
@ -890,19 +893,18 @@ static void resource_user_alloc_locked(grpc_resource_user* resource_user,
resource_user->resource_quota->name, resource_user->name, size,
resource_user->free_pool);
}
if (resource_user->free_pool < 0) {
if (optional_on_done != nullptr) {
resource_user->outstanding_allocations += static_cast<int64_t>(size);
grpc_closure_list_append(&resource_user->on_allocated, optional_on_done,
GRPC_ERROR_NONE);
}
if (!resource_user->allocating) {
resource_user->allocating = true;
GRPC_CLOSURE_SCHED(&resource_user->allocate_closure, GRPC_ERROR_NONE);
}
} else {
GRPC_CLOSURE_SCHED(optional_on_done, GRPC_ERROR_NONE);
if (GPR_LIKELY(resource_user->free_pool >= 0)) return true;
// Slow path: We need to wait for the free pool to refill.
if (optional_on_done != nullptr) {
resource_user->outstanding_allocations += static_cast<int64_t>(size);
grpc_closure_list_append(&resource_user->on_allocated, optional_on_done,
GRPC_ERROR_NONE);
}
if (!resource_user->allocating) {
resource_user->allocating = true;
GRPC_CLOSURE_SCHED(&resource_user->allocate_closure, GRPC_ERROR_NONE);
}
return false;
}
bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user,
@ -926,15 +928,17 @@ bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user,
return true;
}
void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
bool grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
grpc_closure* optional_on_done) {
// TODO(juanlishen): Maybe return immediately if shutting down. Deferring this
// because some tests become flaky after the change.
gpr_mu_lock(&resource_user->mu);
grpc_resource_quota* resource_quota = resource_user->resource_quota;
gpr_atm_no_barrier_fetch_add(&resource_quota->used, size);
resource_user_alloc_locked(resource_user, size, optional_on_done);
const bool ret =
resource_user_alloc_locked(resource_user, size, optional_on_done);
gpr_mu_unlock(&resource_user->mu);
return ret;
}
void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size) {
@ -989,18 +993,22 @@ void grpc_resource_user_slice_allocator_init(
slice_allocator->resource_user = resource_user;
}
void grpc_resource_user_alloc_slices(
bool grpc_resource_user_alloc_slices(
grpc_resource_user_slice_allocator* slice_allocator, size_t length,
size_t count, grpc_slice_buffer* dest) {
if (gpr_atm_no_barrier_load(&slice_allocator->resource_user->shutdown)) {
if (GPR_UNLIKELY(
gpr_atm_no_barrier_load(&slice_allocator->resource_user->shutdown))) {
GRPC_CLOSURE_SCHED(
&slice_allocator->on_allocated,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resource user shutdown"));
return;
return false;
}
slice_allocator->length = length;
slice_allocator->count = count;
slice_allocator->dest = dest;
grpc_resource_user_alloc(slice_allocator->resource_user, count * length,
&slice_allocator->on_allocated);
const bool ret =
grpc_resource_user_alloc(slice_allocator->resource_user, count * length,
&slice_allocator->on_allocated);
if (ret) ru_alloc_slices(slice_allocator);
return ret;
}

@ -124,13 +124,15 @@ bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user,
* If optional_on_done is NULL, then allocate immediately. This may push the
* quota over-limit, at which point reclamation will kick in. The caller is
* always responsible to free the memory eventually.
* If optional_on_done is non-NULL, it will be scheduled without error when the
* allocation has been granted by the quota, and the caller is responsible to
* free the memory eventually. Or it may be scheduled with an error, in which
* case the caller fails to allocate the memory and shouldn't free the memory.
* Returns true if the allocation was successful. Otherwise, if optional_on_done
* is non-NULL, it will be scheduled without error when the allocation has been
* granted by the quota, and the caller is responsible to free the memory
* eventually. Or it may be scheduled with an error, in which case the caller
* fails to allocate the memory and shouldn't free the memory.
*/
void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
grpc_closure* optional_on_done);
bool grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
grpc_closure* optional_on_done)
GRPC_MUST_USE_RESULT;
/* Release memory back to the quota */
void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size);
/* Post a memory reclaimer to the resource user. Only one benign and one
@ -165,9 +167,11 @@ void grpc_resource_user_slice_allocator_init(
grpc_resource_user* resource_user, grpc_iomgr_cb_func cb, void* p);
/* Allocate \a count slices of length \a length into \a dest. Only one request
can be outstanding at a time. */
void grpc_resource_user_alloc_slices(
can be outstanding at a time.
Returns whether the slice was allocated inline in the function. If true,
the \a slice_allocator->on_allocated callback will not be called. */
bool grpc_resource_user_alloc_slices(
grpc_resource_user_slice_allocator* slice_allocator, size_t length,
size_t count, grpc_slice_buffer* dest);
size_t count, grpc_slice_buffer* dest) GRPC_MUST_USE_RESULT;
#endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */

@ -201,9 +201,11 @@ static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
tcp->read_slices = read_slices;
grpc_slice_buffer_reset_and_unref_internal(read_slices);
TCP_REF(tcp, "read");
grpc_resource_user_alloc_slices(&tcp->slice_allocator,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
tcp->read_slices);
if (grpc_resource_user_alloc_slices(&tcp->slice_allocator,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
tcp->read_slices)) {
tcp_read_allocation_done(tcp, GRPC_ERROR_NONE);
}
}
static void custom_write_callback(grpc_custom_socket* socket,

@ -571,7 +571,7 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp,
grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE) {
if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
call_read_cb(tcp, GRPC_ERROR_REF(error));
@ -589,14 +589,17 @@ static void tcp_continue_read(grpc_tcp* tcp) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p alloc_slices", tcp);
}
grpc_resource_user_alloc_slices(&tcp->slice_allocator, target_read_size, 1,
tcp->incoming_buffer);
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p do_read", tcp);
if (GPR_UNLIKELY(!grpc_resource_user_alloc_slices(&tcp->slice_allocator,
target_read_size, 1,
tcp->incoming_buffer))) {
// Wait for allocation.
return;
}
tcp_do_read(tcp);
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
gpr_log(GPR_INFO, "TCP:%p do_read", tcp);
}
tcp_do_read(tcp);
}
static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) {
@ -605,7 +608,7 @@ static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) {
gpr_log(GPR_INFO, "TCP:%p got_read: %s", tcp, grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE) {
if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
call_read_cb(tcp, GRPC_ERROR_REF(error));

@ -18,7 +18,7 @@
#import <XCTest/XCTest.h>
#import <GRPCClient/GRPCCallOptions.h>
#import "../TestBase.h"
/**
* Implements tests as described here:
@ -26,51 +26,6 @@
*
* This is an abstract class that needs to be subclassed. See |+host|.
*/
@interface InteropTests : XCTestCase
/**
* The test suite to run, checking if the current XCTestCase instance is the base class.
* If so, run no tests (disabled). Otherwise, proceed to normal execution.
*/
@property(class, readonly) XCTestSuite *defaultTestSuite;
/**
* Host to send the RPCs to. The base implementation returns nil, which would make all tests to
* fail.
* Override in a subclass to perform these tests against a specific address.
*/
+ (NSString *)host;
/**
* Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior
* when responses are just above or below the max response size. For some reason, the local and
* remote servers enconde responses with different overhead (?), so this is defined per-subclass.
*/
- (int32_t)encodingOverhead;
/**
* DEPRECATED: \a transportType is a deprecated option. Please use \a transport instead.
*
* The type of transport to be used. The base implementation returns default. Subclasses should
* override to appropriate settings.
*/
+ (GRPCTransportType)transportType;
/*
* The transport to be used. The base implementation returns NULL. Subclasses should override to
* appropriate settings.
*/
+ (GRPCTransportID)transport;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)hostNameOverride;
@interface InteropTests : TestBase
@end

@ -18,45 +18,8 @@
#import <XCTest/XCTest.h>
#import <GRPCClient/GRPCCallOptions.h>
#import "../TestBase.h"
@interface StressTests : XCTestCase
/**
* The test suite to run, checking if the current XCTestCase instance is the base class.
* If so, run no tests (disabled). Otherwise, proceed to normal execution.
*/
@property(class, readonly) XCTestSuite *defaultTestSuite;
/**
* Host to send the RPCs to. The base implementation returns nil, which would make all tests to
* fail.
* Override in a subclass to perform these tests against a specific address.
*/
+ (NSString *)host;
/**
* Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior
* when responses are just above or below the max response size. For some reason, the local and
* remote servers enconde responses with different overhead (?), so this is defined per-subclass.
*/
- (int32_t)encodingOverhead;
/**
* The type of transport to be used. The base implementation returns default. Subclasses should
* override to appropriate settings.
*/
+ (GRPCTransportType)transportType;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)hostNameOverride;
@interface StressTests : TestBase
@end

@ -0,0 +1,27 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <XCTest/XCTest.h>
#import "../TestBase.h"
/**
* This is an abstract class that needs to be subclassed. See |+host|.
*/
@interface PerfTests : TestBase
@end

@ -0,0 +1,327 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import "PerfTests.h"
#include <grpc/status.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import <GRPCClient/GRPCCall+Interceptor.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCInterceptor.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <ProtoRPC/ProtoRPC.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <grpc/grpc.h>
#import <grpc/support/log.h>
#import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h"
#import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h"
#import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h"
#import "PerfTestsBlockCallbacks.h"
#define TEST_TIMEOUT 128
extern const char *kCFStreamVarName;
// Convenience constructors for the generated proto messages:
@interface RMTStreamingOutputCallRequest (Constructors)
+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
requestedResponseSize:(NSNumber *)responseSize;
@end
@implementation RMTStreamingOutputCallRequest (Constructors)
+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
requestedResponseSize:(NSNumber *)responseSize {
RMTStreamingOutputCallRequest *request = [self message];
RMTResponseParameters *parameters = [RMTResponseParameters message];
parameters.size = responseSize.intValue;
[request.responseParametersArray addObject:parameters];
request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
return request;
}
@end
@interface DefaultInterceptorFactory : NSObject<GRPCInterceptorFactory>
- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager;
@end
@implementation DefaultInterceptorFactory
- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager {
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
return
[[GRPCInterceptor alloc] initWithInterceptorManager:interceptorManager dispatchQueue:queue];
}
@end
BOOL isUsingCFStream() {
NSString *enabled = @(getenv(kCFStreamVarName));
return [enabled isEqualToString:@"1"];
}
#pragma mark Tests
@implementation PerfTests {
RMTTestService *_service;
}
+ (XCTestSuite *)defaultTestSuite {
if (self == [PerfTests class]) {
return [XCTestSuite testSuiteWithName:@"PerfTestsEmptySuite"];
} else {
return super.defaultTestSuite;
}
}
+ (NSString *)host {
return nil;
}
// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
// message. The number varies as different message.proto is used on different servers. The actual
// number for each interop server is overridden in corresponding derived test classes.
- (int32_t)encodingOverhead {
return 0;
}
+ (GRPCTransportID)transport {
return NULL;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
+ (void)setUp {
setenv("GRPC_TRACE", "tcp", 1);
setenv("GRPC_VERBOSITY", "DEBUG", 1);
NSLog(@"In setUp");
}
- (void)setUp {
self.continueAfterFailure = NO;
[GRPCCall resetHostSettings];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[GRPCCall closeOpenConnections];
#pragma clang diagnostic pop
_service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil;
}
- (void)pingPongV2APIWithRequest:(RMTStreamingOutputCallRequest *)request
numMessages:(int)numMessages
options:(GRPCMutableCallOptions *)options {
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
__block BOOL flowControlEnabled = options.flowControlEnabled;
__block int index = 0;
__block GRPCStreamingProtoCall *call = [self->_service
fullDuplexCallWithResponseHandler:[[PerfTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:^(id message) {
int indexCopy;
@synchronized(self) {
index += 1;
indexCopy = index;
}
if (indexCopy < numMessages) {
[call writeMessage:request];
if (flowControlEnabled) {
[call receiveNextMessage];
}
} else {
[call finish];
}
}
closeCallback:^(NSDictionary *trailingMetadata,
NSError *error) {
[expectation fulfill];
}]
callOptions:options];
[call start];
if (flowControlEnabled) {
[call receiveNextMessage];
}
[call writeMessage:request];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testPingPongRPCWithV2API {
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
// warm up
[self pingPongV2APIWithRequest:request numMessages:1000 options:options];
[self measureBlock:^{
[self pingPongV2APIWithRequest:request numMessages:10000 options:options];
}];
}
- (void)testPingPongRPCWithFlowControl {
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
options.flowControlEnabled = YES;
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
// warm up
[self pingPongV2APIWithRequest:request numMessages:1000 options:options];
[self measureBlock:^{
[self pingPongV2APIWithRequest:request numMessages:10000 options:options];
}];
}
- (void)testPingPongRPCWithInterceptor {
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init] ];
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
// warm up
[self pingPongV2APIWithRequest:request numMessages:1000 options:options];
[self measureBlock:^{
[self pingPongV2APIWithRequest:request numMessages:10000 options:options];
}];
}
- (void)pingPongV1APIWithRequest:(RMTStreamingOutputCallRequest *)request
numMessages:(int)numMessages {
__block int index = 0;
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
[requestsBuffer writeValue:request];
[_service fullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
if (response) {
int indexCopy;
@synchronized(self) {
index += 1;
indexCopy = index;
}
if (indexCopy < numMessages) {
[requestsBuffer writeValue:request];
} else {
[requestsBuffer writesFinishedWithError:nil];
}
}
if (done) {
[expectation fulfill];
}
}];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testPingPongRPCWithV1API {
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
[self pingPongV1APIWithRequest:request numMessages:1000];
[self measureBlock:^{
[self pingPongV1APIWithRequest:request numMessages:10000];
}];
}
- (void)unaryRPCWithRequest:(RMTSimpleRequest *)request
numMessages:(int)numMessages
callOptions:(GRPCMutableCallOptions *)options {
const int kOutstandingRPCs = 10;
NSAssert(numMessages > kOutstandingRPCs, @"Number of RPCs must be > %d", kOutstandingRPCs);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"unaryRPC"];
dispatch_semaphore_t sema = dispatch_semaphore_create(kOutstandingRPCs);
__block int index = 0;
for (int i = 0; i < numMessages; ++i) {
GRPCUnaryProtoCall *call = [_service
unaryCallWithMessage:request
responseHandler:[[PerfTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata,
NSError *error) {
dispatch_semaphore_signal(sema);
@synchronized(self) {
++index;
if (index == numMessages) {
[expectation fulfill];
}
}
}]
callOptions:options];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
[call start];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testUnaryRPC {
// Workaround Apple CFStream bug
if (isUsingCFStream()) {
return;
}
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseSize = 1048576;
request.payload.body = [NSMutableData dataWithLength:1048576];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
// warm up
[self unaryRPCWithRequest:request numMessages:50 callOptions:options];
[self measureBlock:^{
[self unaryRPCWithRequest:request numMessages:50 callOptions:options];
}];
}
@end

@ -0,0 +1,33 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <ProtoRPC/ProtoRPC.h>
// Convenience class to use blocks as callbacks
@interface PerfTestsBlockCallbacks : NSObject<GRPCProtoResponseHandler>
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
writeMessageCallback:(void (^)(void))writeMessageCallback;
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
@end

@ -0,0 +1,80 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import "PerfTestsBlockCallbacks.h"
@implementation PerfTestsBlockCallbacks {
void (^_initialMetadataCallback)(NSDictionary *);
void (^_messageCallback)(id);
void (^_closeCallback)(NSDictionary *, NSError *);
void (^_writeMessageCallback)(void);
dispatch_queue_t _dispatchQueue;
}
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
writeMessageCallback:(void (^)(void))writeMessageCallback {
if ((self = [super init])) {
_initialMetadataCallback = initialMetadataCallback;
_messageCallback = messageCallback;
_closeCallback = closeCallback;
_writeMessageCallback = writeMessageCallback;
_dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
return [self initWithInitialMetadataCallback:initialMetadataCallback
messageCallback:messageCallback
closeCallback:closeCallback
writeMessageCallback:nil];
}
- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
if (_initialMetadataCallback) {
_initialMetadataCallback(initialMetadata);
}
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
if (_messageCallback) {
_messageCallback(message);
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (_closeCallback) {
_closeCallback(trailingMetadata, error);
}
}
- (void)didWriteMessage {
if (_writeMessageCallback) {
_writeMessageCallback();
}
}
- (dispatch_queue_t)dispatchQueue {
return _dispatchQueue;
}
@end

@ -0,0 +1,74 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.h"
// The server address is derived from preprocessor macro, which is
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local cleartext server. */
@interface PerfTestsCFStreamCleartext : PerfTests
@end
@implementation PerfTestsCFStreamCleartext
+ (NSString *)host {
return kLocalCleartextHost;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (void)setUp {
setenv(kCFStreamVarName, "1", 1);
}
- (void)setUp {
[super setUp];
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost];
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_insecure;
}
@end

@ -0,0 +1,80 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.h"
// The server address is derived from preprocessor macro, which is
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local SSL server. */
@interface PerfTestsCFStreamSSL : PerfTests
@end
@implementation PerfTestsCFStreamSSL
+ (NSString *)host {
return kLocalSSLHost;
}
+ (NSString *)PEMRootCertificates {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
NSError *error;
return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error];
}
+ (NSString *)hostNameOverride {
return @"foo.test.google.fr";
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_secure;
}
+ (void)setUp {
setenv(kCFStreamVarName, "1", 1);
}
- (void)setUp {
[super setUp];
// Register test server certificates and name.
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost];
}
@end

@ -0,0 +1,63 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <Cronet/Cronet.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import "../ConfigureCronet.h"
#import "PerfTests.h"
// The server address is derived from preprocessor macro, which is
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
// The Protocol Buffers encoding overhead of remote interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kRemoteInteropServerOverhead = 12;
/** Tests in PerfTests.m, sending the RPCs to a remote SSL server. */
@interface PerfTestsCronet : PerfTests
@end
@implementation PerfTestsCronet
+ (void)setUp {
configureCronet();
[GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]];
[super setUp];
}
+ (NSString *)host {
return kLocalSSLHost;
}
+ (GRPCTransportID)transport {
return gGRPCCoreCronetID;
}
- (int32_t)encodingOverhead {
return kRemoteInteropServerOverhead; // bytes
}
@end

@ -0,0 +1,74 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.h"
// The server address is derived from preprocessor macro, which is
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local cleartext server. */
@interface PerfTestsNoCFStreamCleartext : PerfTests
@end
@implementation PerfTestsNoCFStreamCleartext
+ (NSString *)host {
return kLocalCleartextHost;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (void)setUp {
setenv(kCFStreamVarName, "0", 1);
}
- (void)setUp {
[super setUp];
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost];
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_insecure;
}
@end

@ -0,0 +1,80 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.h"
// The server address is derived from preprocessor macro, which is
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local SSL server. */
@interface PerfTestsNoCFStreamSSL : PerfTests
@end
@implementation PerfTestsNoCFStreamSSL
+ (NSString *)host {
return kLocalSSLHost;
}
+ (NSString *)PEMRootCertificates {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
NSError *error;
return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error];
}
+ (NSString *)hostNameOverride {
return @"foo.test.google.fr";
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_secure;
}
+ (void)setUp {
setenv(kCFStreamVarName, "0", 1);
}
- (void)setUp {
[super setUp];
// Register test server certificates and name.
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost];
}
@end

@ -49,6 +49,14 @@ target 'CronetTests' do
pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true
end
target 'PerfTests' do
platform :ios, '8.0'
grpc_deps
pod 'gRPC/GRPCCoreCronet', :path => GRPC_LOCAL_SRC
pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
end
# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's
# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded
# and before they are installed in the user project.

@ -0,0 +1,65 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <XCTest/XCTest.h>
#import <GRPCClient/GRPCTypes.h>
/**
* This is an abstract class that needs to be subclassed. See |+host|.
*/
@interface TestBase : XCTestCase
/**
* The test suite to run, checking if the current XCTestCase instance is the base class.
* If so, run no tests (disabled). Otherwise, proceed to normal execution.
*/
@property(class, readonly) XCTestSuite *defaultTestSuite;
/**
* Host to send the RPCs to. The base implementation returns nil, which would make all tests to
* fail.
* Override in a subclass to perform these tests against a specific address.
*/
+ (NSString *)host;
/**
* Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior
* when responses are just above or below the max response size. For some reason, the local and
* remote servers enconde responses with different overhead (?), so this is defined per-subclass.
*/
- (int32_t)encodingOverhead;
/*
* The transport to be used. The base implementation returns NULL. Subclasses should override to
* appropriate settings.
*/
+ (GRPCTransportID)transport;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)hostNameOverride;
@end

@ -0,0 +1,50 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import "TestBase.h"
@implementation TestBase : XCTestCase
+ (XCTestSuite *)defaultTestSuite {
return super.defaultTestSuite;
}
+ (NSString *)host {
return nil;
}
// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
// message. The number varies as different message.proto is used on different servers. The actual
// number for each interop server is overridden in corresponding derived test classes.
- (int32_t)encodingOverhead {
return 0;
}
+ (GRPCTransportID)transport {
return NULL;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
@end

@ -50,10 +50,26 @@
ABCB3EEA22F23BF500F0FECE /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487F227782C1006656AD /* APIv2Tests.m */; };
ABCB3EEB22F23BF500F0FECE /* NSErrorUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */; };
B071230B22669EED004B64A1 /* StressTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B071230A22669EED004B64A1 /* StressTests.m */; };
B098FC622331B7EA00029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC632331B7FA00029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC642331B80500029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC652331B82000029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC662331B83900029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B0A420C523299D2200D95F2A /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
B0A420C623299D2D00D95F2A /* ConfigureCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* ConfigureCronet.m */; };
B0BB3F08225E7ABA008DA580 /* NSErrorUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */; };
B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B992266F3CB00A4078D /* StressTestsSSL.m */; };
B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */; };
B0F2D0C4232991CC008C2575 /* PerfTestsBlockCallbacks.h in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D08E23297BC6008C2575 /* PerfTestsBlockCallbacks.h */; };
B0F2D0C5232991CC008C2575 /* PerfTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D08F23297BDD008C2575 /* PerfTestsBlockCallbacks.m */; };
B0F2D0C6232991CC008C2575 /* PerfTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09123297C1A008C2575 /* PerfTests.m */; };
B0F2D0C7232991CC008C2575 /* PerfTests.h in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09323297C28008C2575 /* PerfTests.h */; };
B0F2D0C8232991CC008C2575 /* PerfTestsCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09423297C47008C2575 /* PerfTestsCronet.m */; };
B0F2D0C9232991CC008C2575 /* PerfTestsCFStreamSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09623297CA6008C2575 /* PerfTestsCFStreamSSL.m */; };
B0F2D0CA232991CC008C2575 /* PerfTestsCFStreamCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09823297CBF008C2575 /* PerfTestsCFStreamCleartext.m */; };
B0F2D0CB232991CC008C2575 /* PerfTestsNoCFStreamSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09A23297CF2008C2575 /* PerfTestsNoCFStreamSSL.m */; };
B0F2D0CC232991CC008C2575 /* PerfTestsNoCFStreamCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09C23297D02008C2575 /* PerfTestsNoCFStreamCleartext.m */; };
CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; };
F4E21D69D650D61FE8F02696 /* libPods-TvTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A0A5455106001F60357A4B6 /* libPods-TvTests.a */; };
/* End PBXBuildFile section */
@ -165,9 +181,21 @@
B071230A22669EED004B64A1 /* StressTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTests.m; sourceTree = "<group>"; };
B0BB3EF7225E795F008DA580 /* MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B0BB3EFB225E795F008DA580 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B0C461DF2331AC3F004E17DA /* TestBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestBase.h; sourceTree = "<group>"; };
B0C461E02331AC5C004E17DA /* TestBase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestBase.m; sourceTree = "<group>"; };
B0C5FC172267C77200F192BE /* StressTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StressTests.h; sourceTree = "<group>"; };
B0D39B992266F3CB00A4078D /* StressTestsSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsSSL.m; sourceTree = "<group>"; };
B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsCleartext.m; sourceTree = "<group>"; };
B0F2D08E23297BC6008C2575 /* PerfTestsBlockCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerfTestsBlockCallbacks.h; sourceTree = "<group>"; };
B0F2D08F23297BDD008C2575 /* PerfTestsBlockCallbacks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsBlockCallbacks.m; sourceTree = "<group>"; };
B0F2D09123297C1A008C2575 /* PerfTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTests.m; sourceTree = "<group>"; };
B0F2D09323297C28008C2575 /* PerfTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerfTests.h; sourceTree = "<group>"; };
B0F2D09423297C47008C2575 /* PerfTestsCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsCronet.m; sourceTree = "<group>"; };
B0F2D09623297CA6008C2575 /* PerfTestsCFStreamSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsCFStreamSSL.m; sourceTree = "<group>"; };
B0F2D09823297CBF008C2575 /* PerfTestsCFStreamCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsCFStreamCleartext.m; sourceTree = "<group>"; };
B0F2D09A23297CF2008C2575 /* PerfTestsNoCFStreamSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsNoCFStreamSSL.m; sourceTree = "<group>"; };
B0F2D09C23297D02008C2575 /* PerfTestsNoCFStreamCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsNoCFStreamCleartext.m; sourceTree = "<group>"; };
B0F2D0BA232991BA008C2575 /* PerfTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerfTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = "<group>"; };
B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-APIv2Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = "<group>"; };
@ -243,6 +271,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B0F2D0B7232991BA008C2575 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -409,6 +444,7 @@
635697BE1B14FC11007A7283 = {
isa = PBXGroup;
children = (
B0F2D08D23297B9E008C2575 /* PerfTests */,
5E7F48762277820F006656AD /* InteropTests */,
635697C91B14FC11007A7283 /* Tests */,
63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */,
@ -430,6 +466,7 @@
5EA476F42272816A000F72FC /* InteropTests.xctest */,
5E7F485922775B15006656AD /* CronetTests.xctest */,
ABCB3EDA22F23B9700F0FECE /* TvTests.xctest */,
B0F2D0BA232991BA008C2575 /* PerfTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@ -440,6 +477,8 @@
5E3F148A227918C4007C6D90 /* ConfigureCronet.h */,
5E3F1487227918AA007C6D90 /* ConfigureCronet.m */,
5EAFE8271F8EFB87007F2189 /* version.h */,
B0C461E02331AC5C004E17DA /* TestBase.m */,
B0C461DF2331AC3F004E17DA /* TestBase.h */,
635697D71B14FC11007A7283 /* Supporting Files */,
);
name = Tests;
@ -473,6 +512,22 @@
path = MacTests;
sourceTree = "<group>";
};
B0F2D08D23297B9E008C2575 /* PerfTests */ = {
isa = PBXGroup;
children = (
B0F2D08E23297BC6008C2575 /* PerfTestsBlockCallbacks.h */,
B0F2D08F23297BDD008C2575 /* PerfTestsBlockCallbacks.m */,
B0F2D09123297C1A008C2575 /* PerfTests.m */,
B0F2D09323297C28008C2575 /* PerfTests.h */,
B0F2D09423297C47008C2575 /* PerfTestsCronet.m */,
B0F2D09623297CA6008C2575 /* PerfTestsCFStreamSSL.m */,
B0F2D09823297CBF008C2575 /* PerfTestsCFStreamCleartext.m */,
B0F2D09A23297CF2008C2575 /* PerfTestsNoCFStreamSSL.m */,
B0F2D09C23297D02008C2575 /* PerfTestsNoCFStreamCleartext.m */,
);
path = PerfTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -572,6 +627,23 @@
productReference = B0BB3EF7225E795F008DA580 /* MacTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
B0F2D0B9232991BA008C2575 /* PerfTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = B0F2D0BF232991BA008C2575 /* Build configuration list for PBXNativeTarget "PerfTests" */;
buildPhases = (
B0F2D0B6232991BA008C2575 /* Sources */,
B0F2D0B7232991BA008C2575 /* Frameworks */,
B0F2D0B8232991BA008C2575 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = PerfTests;
productName = PerfTests;
productReference = B0F2D0BA232991BA008C2575 /* PerfTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -602,6 +674,10 @@
CreatedOnToolsVersion = 10.1;
ProvisioningStyle = Automatic;
};
B0F2D0B9232991BA008C2575 = {
CreatedOnToolsVersion = 10.1;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */;
@ -622,6 +698,7 @@
5EA476F32272816A000F72FC /* InteropTests */,
5E7F485822775B15006656AD /* CronetTests */,
ABCB3ED922F23B9700F0FECE /* TvTests */,
B0F2D0B9232991BA008C2575 /* PerfTests */,
);
};
/* End PBXProject section */
@ -666,6 +743,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B0F2D0B8232991BA008C2575 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B0A420C523299D2200D95F2A /* TestCertificates.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@ -889,6 +974,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC652331B82000029C0E /* TestBase.m in Sources */,
5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */,
5E3F148D22792856007C6D90 /* ConfigureCronet.m in Sources */,
5E08D07023021E3B006D76EA /* InteropTestsMultipleChannels.m in Sources */,
@ -904,6 +990,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC642331B80500029C0E /* TestBase.m in Sources */,
5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */,
5E7F488922778B04006656AD /* InteropTestsRemote.m in Sources */,
5EA477042273617B000F72FC /* InteropTestsLocalCleartext.m in Sources */,
@ -916,6 +1003,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC662331B83900029C0E /* TestBase.m in Sources */,
ABCB3EEA22F23BF500F0FECE /* APIv2Tests.m in Sources */,
ABCB3EE822F23BEF00F0FECE /* InteropTestsBlockCallbacks.m in Sources */,
ABCB3EE422F23BEF00F0FECE /* InteropTestsRemote.m in Sources */,
@ -931,6 +1019,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC632331B7FA00029C0E /* TestBase.m in Sources */,
B0BB3F08225E7ABA008DA580 /* NSErrorUnitTests.m in Sources */,
5E7F488D22778C85006656AD /* InteropTestsLocalSSL.m in Sources */,
5E7F488E22778C87006656AD /* InteropTestsLocalCleartext.m in Sources */,
@ -945,6 +1034,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B0F2D0B6232991BA008C2575 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC622331B7EA00029C0E /* TestBase.m in Sources */,
B0A420C623299D2D00D95F2A /* ConfigureCronet.m in Sources */,
B0F2D0C4232991CC008C2575 /* PerfTestsBlockCallbacks.h in Sources */,
B0F2D0C5232991CC008C2575 /* PerfTestsBlockCallbacks.m in Sources */,
B0F2D0C6232991CC008C2575 /* PerfTests.m in Sources */,
B0F2D0C7232991CC008C2575 /* PerfTests.h in Sources */,
B0F2D0C8232991CC008C2575 /* PerfTestsCronet.m in Sources */,
B0F2D0C9232991CC008C2575 /* PerfTestsCFStreamSSL.m in Sources */,
B0F2D0CA232991CC008C2575 /* PerfTestsCFStreamCleartext.m in Sources */,
B0F2D0CB232991CC008C2575 /* PerfTestsNoCFStreamSSL.m in Sources */,
B0F2D0CC232991CC008C2575 /* PerfTestsNoCFStreamCleartext.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
@ -1794,6 +1901,133 @@
};
name = Release;
};
B0F2D0C0232991BA008C2575 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
B0F2D0C1232991BA008C2575 /* Test */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu11;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Test;
};
B0F2D0C2232991BA008C2575 /* Cronet */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu11;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Cronet;
};
B0F2D0C3232991BA008C2575 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu11;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -1863,6 +2097,17 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B0F2D0BF232991BA008C2575 /* Build configuration list for PBXNativeTarget "PerfTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B0F2D0C0232991BA008C2575 /* Debug */,
B0F2D0C1232991BA008C2575 /* Test */,
B0F2D0C2232991BA008C2575 /* Cronet */,
B0F2D0C3232991BA008C2575 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 635697BF1B14FC11007A7283 /* Project object */;

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "PerfTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -17,7 +17,7 @@ licenses(["notice"]) # Apache v2
load("//bazel:grpc_build_system.bzl", "grpc_package", "grpc_proto_library")
grpc_package(
name = "lb",
name = "xds",
visibility = "public",
)

@ -26,7 +26,7 @@ syntax = "proto3";
package envoy.service.load_stats.v2;
import "google/protobuf/duration.proto";
import "src/proto/grpc/lb/v2/eds_for_test.proto";
import "src/proto/grpc/testing/xds/eds_for_test.proto";
// [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs.
message EndpointLoadMetricStats {

@ -380,7 +380,6 @@ def grpc_end2end_tests():
"end2end_tests.h",
],
language = "C++",
visibility = ["//visibility:public"],
deps = [
":cq_verifier",
":ssl_test_data",

@ -119,7 +119,7 @@ static void test_instant_alloc_then_free(void) {
grpc_resource_user* usr = grpc_resource_user_create(q, "usr");
{
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, nullptr);
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, nullptr));
}
{
grpc_core::ExecCtx exec_ctx;
@ -137,7 +137,7 @@ static void test_instant_alloc_free_pair(void) {
grpc_resource_user* usr = grpc_resource_user_create(q, "usr");
{
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, nullptr);
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, nullptr));
grpc_resource_user_free(usr, 1024);
}
grpc_resource_quota_unref(q);
@ -154,7 +154,7 @@ static void test_simple_async_alloc(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
@ -163,6 +163,12 @@ static void test_simple_async_alloc(void) {
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_free(usr, 1024);
}
{
// Now the allocation should be inline.
GPR_ASSERT(grpc_resource_user_alloc(usr, 1024, nullptr));
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_free(usr, 1024);
}
grpc_resource_quota_unref(q);
destroy_user(usr);
}
@ -177,7 +183,7 @@ static void test_async_alloc_blocked_by_size(void) {
gpr_event_init(&ev);
{
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(
&ev, grpc_timeout_milliseconds_to_deadline(100)) == nullptr);
@ -185,7 +191,6 @@ static void test_async_alloc_blocked_by_size(void) {
grpc_resource_quota_resize(q, 1024);
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
;
{
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_free(usr, 1024);
@ -204,11 +209,10 @@ static void test_scavenge(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr1, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr1, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
;
}
{
grpc_core::ExecCtx exec_ctx;
@ -218,11 +222,10 @@ static void test_scavenge(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr2, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr2, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
;
}
{
grpc_core::ExecCtx exec_ctx;
@ -243,16 +246,15 @@ static void test_scavenge_blocked(void) {
{
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr1, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr1, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
;
}
{
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr2, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr2, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(
&ev, grpc_timeout_milliseconds_to_deadline(100)) == nullptr);
@ -263,7 +265,6 @@ static void test_scavenge_blocked(void) {
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
;
}
{
grpc_core::ExecCtx exec_ctx;
@ -284,11 +285,10 @@ static void test_blocked_until_scheduled_reclaim(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
;
}
gpr_event reclaim_done;
gpr_event_init(&reclaim_done);
@ -301,7 +301,7 @@ static void test_blocked_until_scheduled_reclaim(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&reclaim_done,
grpc_timeout_seconds_to_deadline(5)) != nullptr);
@ -328,7 +328,7 @@ static void test_blocked_until_scheduled_reclaim_and_scavenge(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr1, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr1, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
@ -345,7 +345,7 @@ static void test_blocked_until_scheduled_reclaim_and_scavenge(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr2, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr2, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&reclaim_done,
grpc_timeout_seconds_to_deadline(5)) != nullptr);
@ -372,7 +372,7 @@ static void test_blocked_until_scheduled_destructive_reclaim(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
@ -389,7 +389,7 @@ static void test_blocked_until_scheduled_destructive_reclaim(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&reclaim_done,
grpc_timeout_seconds_to_deadline(5)) != nullptr);
@ -451,7 +451,7 @@ static void test_benign_reclaim_is_preferred(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
@ -475,7 +475,7 @@ static void test_benign_reclaim_is_preferred(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&benign_done,
grpc_timeout_seconds_to_deadline(5)) != nullptr);
@ -511,7 +511,7 @@ static void test_multiple_reclaims_can_be_triggered(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
@ -535,7 +535,7 @@ static void test_multiple_reclaims_can_be_triggered(void) {
gpr_event ev;
gpr_event_init(&ev);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&ev));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&benign_done,
grpc_timeout_seconds_to_deadline(5)) != nullptr);
@ -566,7 +566,7 @@ static void test_resource_user_stays_allocated_until_memory_released(void) {
grpc_resource_user* usr = grpc_resource_user_create(q, "usr");
{
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, nullptr);
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, nullptr));
}
{
grpc_core::ExecCtx exec_ctx;
@ -607,7 +607,7 @@ test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_released(
gpr_event allocated;
gpr_event_init(&allocated);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&allocated));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&allocated)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&allocated, grpc_timeout_seconds_to_deadline(
5)) != nullptr);
@ -645,7 +645,7 @@ static void test_reclaimers_can_be_posted_repeatedly(void) {
gpr_event allocated;
gpr_event_init(&allocated);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&allocated));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&allocated)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&allocated,
grpc_timeout_seconds_to_deadline(5)) != nullptr);
@ -666,7 +666,7 @@ static void test_reclaimers_can_be_posted_repeatedly(void) {
gpr_event allocated;
gpr_event_init(&allocated);
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc(usr, 1024, set_event(&allocated));
GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&allocated)));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&allocated, grpc_timeout_seconds_to_deadline(
5)) != nullptr);
@ -701,7 +701,7 @@ static void test_one_slice(void) {
{
const int start_allocs = num_allocs;
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc_slices(&alloc, 1024, 1, &buffer);
GPR_ASSERT(!grpc_resource_user_alloc_slices(&alloc, 1024, 1, &buffer));
grpc_core::ExecCtx::Get()->Flush();
assert_counter_becomes(&num_allocs, start_allocs + 1);
}
@ -733,7 +733,7 @@ static void test_one_slice_deleted_late(void) {
{
const int start_allocs = num_allocs;
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc_slices(&alloc, 1024, 1, &buffer);
GPR_ASSERT(!grpc_resource_user_alloc_slices(&alloc, 1024, 1, &buffer));
grpc_core::ExecCtx::Get()->Flush();
assert_counter_becomes(&num_allocs, start_allocs + 1);
}
@ -775,7 +775,7 @@ static void test_negative_rq_free_pool(void) {
{
const int start_allocs = num_allocs;
grpc_core::ExecCtx exec_ctx;
grpc_resource_user_alloc_slices(&alloc, 1024, 1, &buffer);
GPR_ASSERT(!grpc_resource_user_alloc_slices(&alloc, 1024, 1, &buffer));
grpc_core::ExecCtx::Get()->Flush();
assert_counter_becomes(&num_allocs, start_allocs + 1);
}

@ -434,7 +434,7 @@ grpc_cc_test(
"//:gpr",
"//:grpc",
"//:grpc++",
"//src/proto/grpc/lb/v2:orca_load_report_for_test_proto",
"//src/proto/grpc/testing/xds:orca_load_report_for_test_proto",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
@ -497,8 +497,8 @@ grpc_cc_test(
"//:grpc",
"//:grpc++",
"//:grpc_resolver_fake",
"//src/proto/grpc/lb/v2:eds_for_test_proto",
"//src/proto/grpc/lb/v2:lrs_for_test_proto",
"//src/proto/grpc/testing/xds:eds_for_test_proto",
"//src/proto/grpc/testing/xds:lrs_for_test_proto",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto",

@ -53,8 +53,8 @@
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/server/secure_server_credentials.h"
#include "src/proto/grpc/lb/v2/orca_load_report_for_test.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "src/proto/grpc/testing/xds/orca_load_report_for_test.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/core/util/test_lb_policies.h"
@ -399,26 +399,31 @@ class ClientLbEnd2endTest : public ::testing::Test {
ResetCounters();
}
bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) {
bool WaitForChannelState(
Channel* channel, std::function<bool(grpc_connectivity_state)> predicate,
bool try_to_connect = false, int timeout_seconds = 5) {
const gpr_timespec deadline =
grpc_timeout_seconds_to_deadline(timeout_seconds);
grpc_connectivity_state state;
while ((state = channel->GetState(false /* try_to_connect */)) ==
GRPC_CHANNEL_READY) {
while (true) {
grpc_connectivity_state state = channel->GetState(try_to_connect);
if (predicate(state)) break;
if (!channel->WaitForStateChange(state, deadline)) return false;
}
return true;
}
bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) {
auto predicate = [](grpc_connectivity_state state) {
return state != GRPC_CHANNEL_READY;
};
return WaitForChannelState(channel, predicate, false, timeout_seconds);
}
bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) {
const gpr_timespec deadline =
grpc_timeout_seconds_to_deadline(timeout_seconds);
grpc_connectivity_state state;
while ((state = channel->GetState(true /* try_to_connect */)) !=
GRPC_CHANNEL_READY) {
if (!channel->WaitForStateChange(state, deadline)) return false;
}
return true;
auto predicate = [](grpc_connectivity_state state) {
return state == GRPC_CHANNEL_READY;
};
return WaitForChannelState(channel, predicate, true, timeout_seconds);
}
bool SeenAllServers() {
@ -1176,7 +1181,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) {
auto channel = BuildChannel("round_robin", response_generator);
auto stub = BuildStub(channel);
std::vector<int> ports;
// Start with a single server.
ports.emplace_back(servers_[0]->port_);
response_generator.SetNextResolution(ports);
@ -1187,7 +1191,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) {
EXPECT_EQ(0, servers_[1]->service_.request_count());
EXPECT_EQ(0, servers_[2]->service_.request_count());
servers_[0]->service_.ResetCounters();
// Shutdown one of the servers to be sent in the update.
servers_[1]->Shutdown();
ports.emplace_back(servers_[1]->port_);
@ -1195,7 +1198,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) {
response_generator.SetNextResolution(ports);
WaitForServer(stub, 0, DEBUG_LOCATION);
WaitForServer(stub, 2, DEBUG_LOCATION);
// Send three RPCs, one per server.
for (size_t i = 0; i < kNumServers; ++i) SendRpc(stub);
// The server in shutdown shouldn't receive any.
@ -1279,6 +1281,63 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) {
ASSERT_GT(gpr_time_cmp(deadline, now), 0);
}
TEST_F(ClientLbEnd2endTest, RoundRobinTransientFailure) {
// Start servers and create channel. Channel should go to READY state.
const int kNumServers = 3;
StartServers(kNumServers);
auto response_generator = BuildResolverResponseGenerator();
auto channel = BuildChannel("round_robin", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
EXPECT_TRUE(WaitForChannelReady(channel.get()));
// Now kill the servers. The channel should transition to TRANSIENT_FAILURE.
// TODO(roth): This test should ideally check that even when the
// subchannels are in state CONNECTING for an extended period of time,
// we will still report TRANSIENT_FAILURE. Unfortunately, we don't
// currently have a good way to get a subchannel to report CONNECTING
// for a long period of time, since the servers in this test framework
// are on the loopback interface, which will immediately return a
// "Connection refused" error, so the subchannels will only be in
// CONNECTING state very briefly. When we have time, see if we can
// find a way to fix this.
for (size_t i = 0; i < servers_.size(); ++i) {
servers_[i]->Shutdown();
}
auto predicate = [](grpc_connectivity_state state) {
return state == GRPC_CHANNEL_TRANSIENT_FAILURE;
};
EXPECT_TRUE(WaitForChannelState(channel.get(), predicate));
}
TEST_F(ClientLbEnd2endTest, RoundRobinTransientFailureAtStartup) {
// Create channel and return servers that don't exist. Channel should
// quickly transition into TRANSIENT_FAILURE.
// TODO(roth): This test should ideally check that even when the
// subchannels are in state CONNECTING for an extended period of time,
// we will still report TRANSIENT_FAILURE. Unfortunately, we don't
// currently have a good way to get a subchannel to report CONNECTING
// for a long period of time, since the servers in this test framework
// are on the loopback interface, which will immediately return a
// "Connection refused" error, so the subchannels will only be in
// CONNECTING state very briefly. When we have time, see if we can
// find a way to fix this.
auto response_generator = BuildResolverResponseGenerator();
auto channel = BuildChannel("round_robin", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution({
grpc_pick_unused_port_or_die(),
grpc_pick_unused_port_or_die(),
grpc_pick_unused_port_or_die(),
});
for (size_t i = 0; i < servers_.size(); ++i) {
servers_[i]->Shutdown();
}
auto predicate = [](grpc_connectivity_state state) {
return state == GRPC_CHANNEL_TRANSIENT_FAILURE;
};
EXPECT_TRUE(WaitForChannelState(channel.get(), predicate, true));
}
TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) {
const int kNumServers = 3;
StartServers(kNumServers);

@ -51,9 +51,9 @@
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "src/proto/grpc/lb/v2/eds_for_test.grpc.pb.h"
#include "src/proto/grpc/lb/v2/lrs_for_test.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "src/proto/grpc/testing/xds/eds_for_test.grpc.pb.h"
#include "src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>

@ -28,4 +28,4 @@ tools/run_tests/run_performance_tests.py \
--category smoketest \
-u kbuilder \
--bq_result_table performance_test.performance_experiment_singlevm \
--xml_report reports/singlemachine/sponge_log.xml
--xml_report run_performance_tests/singlemachine/sponge_log.xml

@ -27,7 +27,7 @@ tools/run_tests/run_performance_tests.py \
--remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \
-u kbuilder \
--bq_result_table performance_test.performance_experiment \
--xml_report reports/8core/sponge_log.xml \
--xml_report run_performance_tests/8core/sponge_log.xml \
|| EXIT_CODE=1
# prevent pushing leftover build files to remote hosts in the next step.
@ -41,7 +41,7 @@ tools/run_tests/run_performance_tests.py \
--remote_worker_host grpc-kokoro-performance-server-32core grpc-kokoro-performance-client-32core grpc-kokoro-performance-client2-32core \
-u kbuilder \
--bq_result_table performance_test.performance_experiment_32core \
--xml_report reports/32core/sponge_log.xml \
--xml_report run_performance_tests/32core/sponge_log.xml \
|| EXIT_CODE=1
# prevent pushing leftover build files to remote hosts in the next step.
@ -53,7 +53,7 @@ tools/run_tests/run_performance_tests.py \
--category scalable \
--remote_worker_host grpc-kokoro-performance-windows1 grpc-kokoro-performance-windows2 \
--bq_result_table performance_test.performance_experiment_windows \
--xml_report reports/windows/sponge_log.xml \
--xml_report run_performance_tests/windows/sponge_log.xml \
|| EXIT_CODE=1
exit $EXIT_CODE

@ -27,7 +27,7 @@ tools/run_tests/run_performance_tests.py \
--remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \
-u kbuilder \
--bq_result_table performance_released.performance_experiment \
--xml_report reports/8core/sponge_log.xml \
--xml_report run_performance_tests/8core/sponge_log.xml \
|| EXIT_CODE=1
# prevent pushing leftover build files to remote hosts in the next step.
@ -41,7 +41,7 @@ tools/run_tests/run_performance_tests.py \
--remote_worker_host grpc-kokoro-performance-server-32core grpc-kokoro-performance-client-32core grpc-kokoro-performance-client2-32core \
-u kbuilder \
--bq_result_table performance_released.performance_experiment_32core \
--xml_report reports/32core/sponge_log.xml \
--xml_report run_performance_tests/32core/sponge_log.xml \
|| EXIT_CODE=1
# prevent pushing leftover build files to remote hosts in the next step.
@ -53,7 +53,7 @@ tools/run_tests/run_performance_tests.py \
--category scalable \
--remote_worker_host grpc-kokoro-performance-windows1 grpc-kokoro-performance-windows2 \
--bq_result_table performance_released.performance_experiment_windows \
--xml_report reports/windows/sponge_log.xml \
--xml_report run_performance_tests/windows/sponge_log.xml \
|| EXIT_CODE=1
exit $EXIT_CODE

@ -135,7 +135,7 @@ def create_scenario_jobspec(scenario_json,
return jobset.JobSpec(
cmdline=[cmd],
shortname='qps_json_driver.%s' % scenario_json['name'],
shortname='%s' % scenario_json['name'],
timeout_seconds=_SCENARIO_TIMEOUT,
shell=True,
verbose_success=True)
@ -153,7 +153,7 @@ def create_quit_jobspec(workers, remote_host=None):
return jobset.JobSpec(
cmdline=[cmd],
shortname='qps_json_driver.quit',
shortname='shutdown_workers',
timeout_seconds=_QUIT_WORKER_TIMEOUT,
shell=True,
verbose_success=True)
@ -670,6 +670,8 @@ def main():
worker.start()
jobs = [scenario.jobspec]
if scenario.workers:
# TODO(jtattermusch): ideally the "quit" job won't show up
# in the report
jobs.append(
create_quit_jobspec(
scenario.workers,
@ -707,7 +709,10 @@ def main():
'%s/index.html' % args.flame_graph_reports, profile_output_files)
report_utils.render_junit_xml_report(
merged_resultset, args.xml_report, suite_name='benchmarks')
merged_resultset,
args.xml_report,
suite_name='benchmarks',
multi_target=True)
if total_scenario_failures > 0 or qps_workers_killed > 0:
print('%s scenarios failed and %s qps worker jobs killed' %

@ -66,10 +66,8 @@ def _matrix_job_logfilename(shortname_for_multi_target):
# for the corresponding 'sponge_log.xml' report.
# the shortname_for_multi_target component must be set to match the sponge_log.xml location
# because the top-level render_junit_xml_report is called with multi_target=True
s = '%s/%s/%s' % (_MATRIX_REPORT_NAME, shortname_for_multi_target,
'sponge_log.log')
print(s)
return s
return '%s/%s/%s' % (_MATRIX_REPORT_NAME, shortname_for_multi_target,
'sponge_log.log')
def _docker_jobspec(name,

Loading…
Cancel
Save