Merge branch 'master' into delay_fail_on_failed_rpc

pull/23629/head
Eric Gribkoff 5 years ago committed by GitHub
commit 5b6997d5a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 2
      .github/ISSUE_TEMPLATE/cleanup_request.md
  3. 2
      .github/ISSUE_TEMPLATE/feature_request.md
  4. 2
      .github/ISSUE_TEMPLATE/question.md
  5. 2
      .github/pull_request_template.md
  6. 7
      CMakeLists.txt
  7. 27
      Makefile
  8. 9
      bazel/python_rules.bzl
  9. 2
      bazel/test/python_test_repo/BUILD
  10. 3
      bazel/test/python_test_repo/WORKSPACE
  11. 165
      bazel/test/python_test_repo/namespaced/upper/example/BUILD
  12. 35
      bazel/test/python_test_repo/namespaced/upper/example/import_no_strip_test.py
  13. 35
      bazel/test/python_test_repo/namespaced/upper/example/import_strip_test.py
  14. 27
      bazel/test/python_test_repo/namespaced/upper/example/namespaced_dependency.proto
  15. 38
      bazel/test/python_test_repo/namespaced/upper/example/namespaced_example.proto
  16. 35
      bazel/test/python_test_repo/namespaced/upper/example/no_import_no_strip_test.py
  17. 35
      bazel/test/python_test_repo/namespaced/upper/example/no_import_strip_test.py
  18. 1
      build_autogenerated.yaml
  19. 59
      src/boringssl/gen_build_yaml.py
  20. 9
      src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc
  21. 9
      src/proto/grpc/testing/xds/v3/BUILD
  22. 17
      src/proto/grpc/testing/xds/v3/discovery.proto
  23. 89
      src/proto/grpc/testing/xds/v3/status.proto
  24. 9
      src/ruby/end2end/call_credentials_returning_bad_metadata_doesnt_kill_background_thread_driver.rb
  25. 21
      src/ruby/end2end/call_credentials_timeout_driver.rb
  26. 13
      src/ruby/end2end/channel_closing_driver.rb
  27. 35
      src/ruby/end2end/end2end_common.rb
  28. 41
      src/ruby/end2end/graceful_sig_handling_driver.rb
  29. 37
      src/ruby/end2end/graceful_sig_stop_driver.rb
  30. 38
      src/ruby/end2end/sig_handling_driver.rb
  31. 10
      src/ruby/end2end/sig_int_during_channel_watch_client.rb
  32. 9
      src/ruby/end2end/sig_int_during_channel_watch_driver.rb
  33. 2
      test/core/transport/byte_stream_test.cc
  34. 2
      test/core/transport/connectivity_state_test.cc
  35. 2
      test/core/transport/static_metadata_test.cc
  36. 4
      test/core/transport/status_conversion_test.cc
  37. 5
      test/core/transport/status_metadata_test.cc
  38. 285
      tools/run_tests/run_xds_tests.py

@ -2,7 +2,7 @@
name: Report a bug
about: Create a report to help us improve
labels: kind/bug, priority/P2
assignees: donnadionne
assignees: markdroth
---

@ -2,7 +2,7 @@
name: Request a cleanup
about: Suggest a cleanup in our repository
labels: kind/internal cleanup, priority/P2
assignees: donnadionne
assignees: markdroth
---

@ -2,7 +2,7 @@
name: Request a feature
about: Suggest an idea for this project
labels: kind/enhancement, priority/P2
assignees: donnadionne
assignees: markdroth
---

@ -2,7 +2,7 @@
name: Ask a question
about: Ask a question
labels: kind/question, priority/P3
assignees: donnadionne
assignees: markdroth
---

@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be
-->
@donnadionne
@markdroth

@ -478,9 +478,6 @@ protobuf_generate_grpc_cpp(
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/xds/v3/route.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/xds/v3/status.proto
)
protobuf_generate_grpc_cpp(
test/core/tsi/alts/fake_handshaker/handshaker.proto
)
@ -14916,10 +14913,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/status.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/status.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/status.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/status.grpc.pb.h
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds_end2end_test.cc
third_party/googletest/googletest/src/gtest-all.cc

@ -2977,12 +2977,12 @@ $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc: src/proto/grpc/testing/xds/v3/discovery.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.pb.cc
$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc: src/proto/grpc/testing/xds/v3/discovery.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.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/v3/discovery.grpc.pb.cc: src/proto/grpc/testing/xds/v3/discovery.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.grpc.pb.cc
$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc: src/proto/grpc/testing/xds/v3/discovery.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.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) $<
@ -3132,22 +3132,6 @@ $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc: src/proto/grpc/testing
$(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/v3/status.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/xds/v3/status.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/src/proto/grpc/testing/xds/v3/status.pb.cc: src/proto/grpc/testing/xds/v3/status.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/v3/status.grpc.pb.cc: src/proto/grpc/testing/xds/v3/status.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/status.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)/test/core/tsi/alts/fake_handshaker/handshaker.pb.cc: protoc_dep_error
$(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.cc: protoc_dep_error
@ -19125,7 +19109,6 @@ XDS_END2END_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/xds/v3/status.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.grpc.pb.cc \
test/cpp/end2end/test_service_impl.cc \
test/cpp/end2end/xds_end2end_test.cc \
@ -19206,8 +19189,6 @@ $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/xds/v3/regex.o: $(LIBDIR)/$(CONFIG)/
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/xds/v3/route.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/xds/v3/status.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
@ -19219,8 +19200,8 @@ ifneq ($(NO_DEPS),true)
-include $(XDS_END2END_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_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/lds_rds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_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 $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_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/lds_rds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_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 $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/status.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_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/lds_rds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_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 $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_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/lds_rds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_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 $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc
XDS_INTEROP_CLIENT_SRC = \

@ -53,7 +53,7 @@ def _generate_py_impl(context):
imports = []
if out_dir.import_path:
imports.append("__main__/%s" % out_dir.import_path)
imports.append("%s/%s/%s" % (context.workspace_name, context.label.package, out_dir.import_path))
return [
DefaultInfo(files = depset(direct = out_files)),
@ -164,15 +164,12 @@ def _generate_pb2_grpc_src_impl(context):
mnemonic = "ProtocInvocation",
)
imports = []
if out_dir.import_path:
imports.append("__main__/%s" % out_dir.import_path)
return [
DefaultInfo(files = depset(direct = out_files)),
PyInfo(
transitive_sources = depset(),
imports = depset(direct = imports),
# Imports are already configured by the generated py impl
imports = depset(),
),
]

@ -69,6 +69,8 @@ py2and3_test(
# Test compatibility of py_proto_library and py_grpc_library rules with
# proto_library targets as deps when the latter use import_prefix and/or
# strip_import_prefix arguments
#
# See namespaced/upper/example for more encompassing tests.
proto_library(
name = "helloworld_moved_proto",
srcs = ["helloworld.proto"],

@ -3,6 +3,9 @@ local_repository(
path = "../../..",
)
# Ensure rules don't rely on __main__ naming convention.
workspace(name = "python_test_repo")
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()

@ -0,0 +1,165 @@
# gRPC Bazel BUILD file.
#
# Copyright 2020 The gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_proto//proto:defs.bzl", "proto_library")
load(
"@com_github_grpc_grpc//bazel:python_rules.bzl",
"py2and3_test",
"py_grpc_library",
"py_proto_library",
)
_IMPORT_PREFIX = "foo/bar"
_STRIP_PREFIX = "/%s" % package_name()
proto_library(
name = "import_no_strip_proto",
srcs = ["namespaced_example.proto"],
import_prefix = _IMPORT_PREFIX,
strip_import_prefix = None,
)
proto_library(
name = "import_strip_proto",
srcs = ["namespaced_example.proto"],
import_prefix = _IMPORT_PREFIX,
strip_import_prefix = _STRIP_PREFIX,
)
proto_library(
name = "no_import_no_strip_proto",
srcs = ["namespaced_example.proto"],
import_prefix = None,
strip_import_prefix = None,
)
proto_library(
name = "no_import_strip_proto",
srcs = ["namespaced_example.proto"],
import_prefix = None,
strip_import_prefix = _STRIP_PREFIX,
)
py_proto_library(
name = "import_no_strip_py_pb2",
deps = ["import_no_strip_proto"],
)
py_grpc_library(
name = "import_no_strip_py_pb2_grpc",
srcs = ["import_no_strip_proto"],
deps = ["import_no_strip_py_pb2"],
)
py_proto_library(
name = "import_strip_py_pb2",
deps = ["import_strip_proto"],
)
py_grpc_library(
name = "import_strip_py_pb2_grpc",
srcs = ["import_strip_proto"],
deps = ["import_strip_py_pb2"],
)
py_proto_library(
name = "no_import_no_strip_py_pb2",
deps = ["no_import_no_strip_proto"],
)
py_grpc_library(
name = "no_import_no_strip_py_pb2_grpc",
srcs = ["no_import_no_strip_proto"],
deps = ["no_import_no_strip_py_pb2"],
)
py_proto_library(
name = "no_import_strip_py_pb2",
deps = ["no_import_strip_proto"],
)
py_grpc_library(
name = "no_import_strip_py_pb2_grpc",
srcs = ["no_import_strip_proto"],
deps = ["no_import_strip_py_pb2"],
)
#################
# Namespace Tests
#################
# Most examples with protos have all proto packages rooted at the workspace root. i.e. google/api has
# a directory structure:
# - WORKSPACE
# - /google
# - /api
# - files.proto
#
# But if you can't anchor the protos at the root, you have to use strip and import prefixes. This results
# in the following directory layout for python, which needs to properly be added to the imports.
#
# No Import or Strip (Can't compile if there are any proto dependencies)
# bazel-out/darwin-fastbuild/bin/namespaced/upper/example/namespaced_example_pb2.py
#
# No import Prefix (Can't compile if there are any proto dependencies)
# bazel-out/darwin-fastbuild/bin/namespaced/upper/example/_virtual_imports/namespaced_example_proto/namespaced_example_pb2.py
#
# No strip prefix (Can't compile if there are any proto dependencies)
# bazel-out/darwin-fastbuild/bin/namespaced/upper/example/_virtual_imports/namespaced_example_proto/upper/example/namespaced/upper/example/namespaced_example_pb2.py
#
# Both Import and Strip
# bazel-out/darwin-fastbuild/bin/namespaced/upper/example/_virtual_imports/namespaced_example_proto/upper/example/namespaced_example_pb2.py
py2and3_test(
"import_no_strip_test",
srcs = ["import_no_strip_test.py"],
main = "import_no_strip_test.py",
deps = [
":import_no_strip_py_pb2",
":import_no_strip_py_pb2_grpc",
],
)
py2and3_test(
"import_strip_test",
srcs = ["import_strip_test.py"],
main = "import_strip_test.py",
deps = [
":import_strip_py_pb2",
":import_strip_py_pb2_grpc",
],
)
py2and3_test(
"no_import_no_strip_test",
srcs = ["no_import_no_strip_test.py"],
main = "no_import_no_strip_test.py",
deps = [
":no_import_no_strip_py_pb2",
":no_import_no_strip_py_pb2_grpc",
],
)
py2and3_test(
"no_import_strip_test",
srcs = ["no_import_strip_test.py"],
main = "no_import_strip_test.py",
deps = [
":no_import_strip_py_pb2",
":no_import_strip_py_pb2_grpc",
],
)

@ -0,0 +1,35 @@
# Copyright 2020 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import unittest
class ImportTest(unittest.TestCase):
def test_import(self):
from foo.bar.namespaced.upper.example.namespaced_example_pb2 import NamespacedExample
namespaced_example = NamespacedExample()
namespaced_example.value = "hello"
# Dummy assert, important part is namespaced example was imported.
self.assertEqual(namespaced_example.value, "hello")
def test_grpc(self):
from foo.bar.namespaced.upper.example.namespaced_example_pb2_grpc import NamespacedServiceStub
# No error from import
self.assertEqual(1, 1)
if __name__ == '__main__':
logging.basicConfig()
unittest.main()

@ -0,0 +1,35 @@
# Copyright 2020 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import unittest
class ImportTest(unittest.TestCase):
def test_import(self):
from foo.bar.namespaced_example_pb2 import NamespacedExample
namespaced_example = NamespacedExample()
namespaced_example.value = "hello"
# Dummy assert, important part is namespaced example was imported.
self.assertEqual(namespaced_example.value, "hello")
def test_grpc(self):
from foo.bar.namespaced_example_pb2_grpc import NamespacedServiceStub
# No error from import
self.assertEqual(1, 1)
if __name__ == '__main__':
logging.basicConfig()
unittest.main()

@ -0,0 +1,27 @@
// Copyright 2020 The gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.namespaced";
option java_outer_classname = "NamespacedDependencyProtos";
option objc_class_prefix = "NEP";
package upper.example;
message NamespacedDependency {
int32 value = 1;
}

@ -0,0 +1,38 @@
// Copyright 2020 The gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.namespaced";
option java_outer_classname = "NamespacedExampleProtos";
option objc_class_prefix = "NEP";
package upper.example;
// TODO: dependencies are still broken
// Need to do something like this: https://packaging.python.org/guides/packaging-namespace-packages/
// import "upper/example/namespaced_dependency.proto";
message NamespacedExample {
string value = 1;
// TODO: dependencies are still broken
// NamespacedDependency dependency = 2;
}
service NamespacedService {
rpc SayHello (NamespacedExample) returns (NamespacedExample) {}
}

@ -0,0 +1,35 @@
# Copyright 2020 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import unittest
class ImportTest(unittest.TestCase):
def test_import(self):
from namespaced.upper.example.namespaced_example_pb2 import NamespacedExample
namespaced_example = NamespacedExample()
namespaced_example.value = "hello"
# Dummy assert, important part is namespaced example was imported.
self.assertEqual(namespaced_example.value, "hello")
def test_grpc(self):
from namespaced.upper.example.namespaced_example_pb2_grpc import NamespacedServiceStub
# No error from import
self.assertEqual(1, 1)
if __name__ == '__main__':
logging.basicConfig()
unittest.main()

@ -0,0 +1,35 @@
# Copyright 2020 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import unittest
class ImportTest(unittest.TestCase):
def test_import(self):
from namespaced_example_pb2 import NamespacedExample
namespaced_example = NamespacedExample()
namespaced_example.value = "hello"
# Dummy assert, important part is namespaced example was imported.
self.assertEqual(namespaced_example.value, "hello")
def test_grpc(self):
from namespaced_example_pb2_grpc import NamespacedServiceStub
# No error from import
self.assertEqual(1, 1)
if __name__ == '__main__':
logging.basicConfig()
unittest.main()

@ -7598,7 +7598,6 @@ targets:
- src/proto/grpc/testing/xds/v3/range.proto
- src/proto/grpc/testing/xds/v3/regex.proto
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/status.proto
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds_end2end_test.cc
deps:

@ -13,24 +13,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import shutil
import sys
import json
import os
import sys
import yaml
sys.dont_write_bytecode = True
boring_ssl_root = os.path.abspath(
sources_path = os.path.abspath(
os.path.join(os.path.dirname(sys.argv[0]),
'../../third_party/boringssl-with-bazel/src'))
sys.path.append(os.path.join(boring_ssl_root, 'util'))
try:
import generate_build_files
except ImportError:
print(yaml.dump({}))
sys.exit()
'../../third_party/boringssl-with-bazel/sources.json'))
with open(sources_path, 'r') as s:
sources = json.load(s)
def map_dir(filename):
@ -38,18 +30,19 @@ def map_dir(filename):
class Grpc(object):
"""Implements a "platform" in the sense of boringssl's generate_build_files.py"""
yaml = None
"""Adapter for boring-SSL json sources files. """
def WriteFiles(self, files, asm_outputs):
test_binaries = ['ssl_test', 'crypto_test']
def __init__(self, sources):
self.yaml = None
self.WriteFiles(sources)
def WriteFiles(self, files):
test_binaries = ['ssl_test', 'crypto_test']
self.yaml = {
'#':
'generated with src/boringssl/gen_build_yaml.py',
'raw_boringssl_build_output_for_debugging': {
'files': files,
'asm_outputs': asm_outputs,
},
'libs': [
{
@ -120,29 +113,5 @@ class Grpc(object):
}
os.chdir(os.path.dirname(sys.argv[0]))
os.mkdir('src')
try:
for f in os.listdir(boring_ssl_root):
os.symlink(os.path.join(boring_ssl_root, f), os.path.join('src', f))
grpc_platform = Grpc()
# We use a hack to run boringssl's util/generate_build_files.py as part of this script.
# The call will populate "grpc_platform" with boringssl's source file metadata.
# As a side effect this script generates err_data.c and crypto_test_data.cc (requires golang)
# Both of these files are already available under third_party/boringssl-with-bazel
# so we don't need to generate them again, but there's no option to disable that behavior.
# - crypto_test_data.cc is required to run boringssl_crypto_test but we already
# use the copy under third_party/boringssl-with-bazel so we just delete it
# - err_data.c is already under third_party/boringssl-with-bazel so we just delete it
generate_build_files.main([grpc_platform])
print(yaml.dump(grpc_platform.yaml))
finally:
# we don't want err_data.c and crypto_test_data.cc (see comment above)
if os.path.exists('err_data.c'):
os.remove('err_data.c')
if os.path.exists('crypto_test_data.cc'):
os.remove('crypto_test_data.cc')
shutil.rmtree('src')
grpc_platform = Grpc(sources)
print(yaml.dump(grpc_platform.yaml))

@ -187,7 +187,7 @@ class XdsRoutingLb : public LoadBalancingPolicy {
RefCountedPtr<XdsRoutingLb> xds_routing_policy_;
// Points to the corresponding key in XdsRoutingLb::actions_.
const std::string& name_;
const std::string name_;
OrphanablePtr<LoadBalancingPolicy> child_policy_;
@ -407,9 +407,10 @@ void XdsRoutingLb::UpdateLocked(UpdateArgs args) {
const RefCountedPtr<LoadBalancingPolicy::Config>& config = p.second;
auto it = actions_.find(name);
if (it == actions_.end()) {
it = actions_.emplace(std::make_pair(name, nullptr)).first;
it->second = MakeOrphanable<XdsRoutingChild>(
Ref(DEBUG_LOCATION, "XdsRoutingChild"), it->first);
it = actions_
.emplace(name, MakeOrphanable<XdsRoutingChild>(
Ref(DEBUG_LOCATION, "XdsRoutingChild"), name))
.first;
}
it->second->UpdateLocked(config, args.addresses, args.args);
}

@ -46,14 +46,6 @@ grpc_proto_library(
],
)
grpc_proto_library(
name = "status_proto",
srcs = [
"status.proto",
],
well_known_protos = True,
)
grpc_proto_library(
name = "discovery_proto",
srcs = [
@ -62,7 +54,6 @@ grpc_proto_library(
well_known_protos = True,
deps = [
"base_proto",
"status_proto",
],
)

@ -21,7 +21,20 @@ package envoy.service.discovery.v3;
import "src/proto/grpc/testing/xds/v3/base.proto";
import "google/protobuf/any.proto";
import "src/proto/grpc/testing/xds/v3/status.proto";
message Status {
// The status code, which should be an enum value of [google.rpc.Code][].
int32 code = 1;
// A developer-facing error message, which should be in English. Any
// user-facing error message should be localized and sent in the
// [google.rpc.Status.details][] field, or localized by the client.
string message = 2;
// A list of messages that carry the error details. There is a common set of
// message types for APIs to use.
repeated google.protobuf.Any details = 3;
}
// [#protodoc-title: Common discovery API components]
@ -66,7 +79,7 @@ message DiscoveryRequest {
// failed to update configuration. The *message* field in *error_details* provides the Envoy
// internal exception related to the failure. It is only intended for consumption during manual
// debugging, the string provided is not guaranteed to be stable across Envoy versions.
google.rpc.Status error_detail = 6;
Status error_detail = 6;
}
// [#next-free-field: 7]

@ -1,89 +0,0 @@
// Copyright 2020 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Local copy of Google status proto file, used for testing only.
syntax = "proto3";
package google.rpc;
import "google/protobuf/any.proto";
// The `Status` type defines a logical error model that is suitable for different
// programming environments, including REST APIs and RPC APIs. It is used by
// [gRPC](https://github.com/grpc). The error model is designed to be:
//
// - Simple to use and understand for most users
// - Flexible enough to meet unexpected needs
//
// # Overview
//
// The `Status` message contains three pieces of data: error code, error message,
// and error details. The error code should be an enum value of
// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The
// error message should be a developer-facing English message that helps
// developers *understand* and *resolve* the error. If a localized user-facing
// error message is needed, put the localized message in the error details or
// localize it in the client. The optional error details may contain arbitrary
// information about the error. There is a predefined set of error detail types
// in the package `google.rpc` that can be used for common error conditions.
//
// # Language mapping
//
// The `Status` message is the logical representation of the error model, but it
// is not necessarily the actual wire format. When the `Status` message is
// exposed in different client libraries and different wire protocols, it can be
// mapped differently. For example, it will likely be mapped to some exceptions
// in Java, but more likely mapped to some error codes in C.
//
// # Other uses
//
// The error model and the `Status` message can be used in a variety of
// environments, either with or without APIs, to provide a
// consistent developer experience across different environments.
//
// Example uses of this error model include:
//
// - Partial errors. If a service needs to return partial errors to the client,
// it may embed the `Status` in the normal response to indicate the partial
// errors.
//
// - Workflow errors. A typical workflow has multiple steps. Each step may
// have a `Status` message for error reporting.
//
// - Batch operations. If a client uses batch request and batch response, the
// `Status` message should be used directly inside batch response, one for
// each error sub-response.
//
// - Asynchronous operations. If an API call embeds asynchronous operation
// results in its response, the status of those operations should be
// represented directly using the `Status` message.
//
// - Logging. If some API errors are stored in logs, the message `Status` could
// be used directly after any stripping needed for security/privacy reasons.
message Status {
// The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
int32 code = 1;
// A developer-facing error message, which should be in English. Any
// user-facing error message should be localized and sent in the
// [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
string message = 2;
// A list of messages that carry the error details. There is a common set of
// message types for APIs to use.
repeated google.protobuf.Any details = 3;
}

@ -49,15 +49,6 @@ def create_server_creds
true) # force client auth
end
# Useful to update a value within a do block
class MutableValue
attr_accessor :value
def initialize(value)
@value = value
end
end
def run_rpc_expect_unavailable(stub)
exception = nil
begin

@ -49,15 +49,6 @@ def create_server_creds
true) # force client auth
end
# Useful to update a value within a do block
class MutableValue
attr_accessor :value
def initialize(value)
@value = value
end
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def main
@ -136,10 +127,16 @@ def main
STDERR.puts 'now perform another RPC and expect OK...'
stub.echo(Echo::EchoRequest.new(request: 'hello'), deadline: Time.now + 10)
jwt_aud_uri_extraction_success_count_mu.synchronize do
if jwt_aud_uri_extraction_success_count.value != 2003
if jwt_aud_uri_extraction_success_count.value < 4
fail "Expected auth metadata plugin callback to be ran with the jwt_aud_uri
parameter matching its expected value at least 4 times (at least 1 out of the 2000
initial expected-to-timeout RPCs should have caused this by now, and all three of the
successful RPCs should have caused this). This test isn't doing what it's meant to do."
end
unless jwt_aud_uri_failure_values.empty?
fail "Expected to get jwt_aud_uri:#{expected_jwt_aud_uri} passed to call creds
user callback 2003 times, but it was only passed to the call creds user callback
#{jwt_aud_uri_extraction_success_count.value} times. This suggests that either:
user callback every time that it was invoked, but it did not match the expected value
in #{jwt_aud_uri_failure_values.size} invocations. This suggests that either:
a) the expected jwt_aud_uri value is incorrect
b) there is some corruption of the jwt_aud_uri argument
Here are are the values of the jwt_aud_uri parameter that were passed to the call

@ -31,8 +31,17 @@ def main
sleep 3
begin
Timeout.timeout(10) do
control_stub.shutdown(ClientControl::Void.new)
Timeout.timeout(20) do
loop do
begin
control_stub.shutdown(ClientControl::Void.new)
break
rescue GRPC::BadStatus => e
STDERR.puts "control_stub.shutdown RPC received error:|#{e}|. " \
"This could mean that that child process e.g. isn't running yet, " \
"so we'll retry the RPC"
end
end
Process.wait(client_pid)
end
rescue Timeout::Error

@ -33,12 +33,47 @@ require_relative '../spec/support/helpers'
include GRPC::Spec::Helpers
# Useful to update a value within a do block
class MutableValue
attr_accessor :value
def initialize(value)
@value = value
end
end
# GreeterServer is simple server that implements the Helloworld Greeter server.
# This service also has a mechanism to wait for a timeout until the first
# RPC has been received, which is useful for synchronizing between parent
# and child processes.
class EchoServerImpl < Echo::EchoServer::Service
def initialize
@first_rpc_received_mu = Mutex.new
@first_rpc_received_cv = ConditionVariable.new
@first_rpc_received = MutableValue.new(false)
end
# say_hello implements the SayHello rpc method.
def echo(echo_req, _)
@first_rpc_received_mu.synchronize do
@first_rpc_received.value = true
@first_rpc_received_cv.broadcast
end
Echo::EchoReply.new(response: echo_req.request)
end
def wait_for_first_rpc_received(timeout_seconds)
Timeout.timeout(timeout_seconds) do
@first_rpc_received_mu.synchronize do
until @first_rpc_received.value
@first_rpc_received_cv.wait(@first_rpc_received_mu)
end
end
end
rescue => e
fail "Received error:|#{e}| while waiting for #{timeout_seconds} " \
'seconds to receive the first RPC'
end
end
# ServerRunner starts an "echo server" that test clients can make calls to

@ -19,51 +19,23 @@
require_relative './end2end_common'
# A service that calls back it's received_rpc_callback
# upon receiving an RPC. Used for synchronization/waiting
# for child process to start.
class ClientStartedService < Echo::EchoServer::Service
def initialize(received_rpc_callback)
@received_rpc_callback = received_rpc_callback
end
def echo(echo_req, _)
@received_rpc_callback.call unless @received_rpc_callback.nil?
@received_rpc_callback = nil
Echo::EchoReply.new(response: echo_req.request)
end
end
def main
STDERR.puts 'start server'
client_started = false
client_started_mu = Mutex.new
client_started_cv = ConditionVariable.new
received_rpc_callback = proc do
client_started_mu.synchronize do
client_started = true
client_started_cv.signal
end
end
client_started_service = ClientStartedService.new(received_rpc_callback)
server_runner = ServerRunner.new(client_started_service)
echo_service = EchoServerImpl.new
server_runner = ServerRunner.new(echo_service)
server_port = server_runner.run
STDERR.puts 'start client'
control_stub, client_pid = start_client('graceful_sig_handling_client.rb', server_port)
client_started_mu.synchronize do
client_started_cv.wait(client_started_mu) until client_started
end
# use receipt of one RPC to indicate that the child process is
# ready
echo_service.wait_for_first_rpc_received(20)
# now get the client to send an RPC
control_stub.do_echo_rpc(
ClientControl::DoEchoRpcRequest.new(request: 'hello'))
STDERR.puts 'killing client'
Process.kill('SIGINT', client_pid)
Process.wait(client_pid)
client_exit_status = $CHILD_STATUS
if client_exit_status.exited?
if client_exit_status.exitstatus != 0
STDERR.puts 'Client did not close gracefully'
@ -75,7 +47,6 @@ def main
end
STDERR.puts 'Client ended gracefully'
# no need to call cleanup, client should already be dead
server_runner.stop
end

@ -19,43 +19,16 @@
require_relative './end2end_common'
# A service that calls back it's received_rpc_callback
# upon receiving an RPC. Used for synchronization/waiting
# for child process to start.
class ClientStartedService < Echo::EchoServer::Service
def initialize(received_rpc_callback)
@received_rpc_callback = received_rpc_callback
end
def echo(echo_req, _)
@received_rpc_callback.call unless @received_rpc_callback.nil?
@received_rpc_callback = nil
Echo::EchoReply.new(response: echo_req.request)
end
end
def main
STDERR.puts 'start server'
client_started = false
client_started_mu = Mutex.new
client_started_cv = ConditionVariable.new
received_rpc_callback = proc do
client_started_mu.synchronize do
client_started = true
client_started_cv.signal
end
end
client_started_service = ClientStartedService.new(received_rpc_callback)
server_runner = ServerRunner.new(client_started_service)
echo_service = EchoServerImpl.new
server_runner = ServerRunner.new(echo_service)
server_port = server_runner.run
STDERR.puts 'start client'
control_stub, client_pid = start_client('./graceful_sig_stop_client.rb', server_port)
client_started_mu.synchronize do
client_started_cv.wait(client_started_mu) until client_started
end
# use receipt of one RPC to indicate that the child process is
# ready
echo_service.wait_for_first_rpc_received(20)
cleanup(control_stub, client_pid, server_runner)
end

@ -19,43 +19,16 @@
require_relative './end2end_common'
# A service that calls back it's received_rpc_callback
# upon receiving an RPC. Used for synchronization/waiting
# for child process to start.
class ClientStartedService < Echo::EchoServer::Service
def initialize(received_rpc_callback)
@received_rpc_callback = received_rpc_callback
end
def echo(echo_req, _)
@received_rpc_callback.call unless @received_rpc_callback.nil?
@received_rpc_callback = nil
Echo::EchoReply.new(response: echo_req.request)
end
end
def main
STDERR.puts 'start server'
client_started = false
client_started_mu = Mutex.new
client_started_cv = ConditionVariable.new
received_rpc_callback = proc do
client_started_mu.synchronize do
client_started = true
client_started_cv.signal
end
end
client_started_service = ClientStartedService.new(received_rpc_callback)
server_runner = ServerRunner.new(client_started_service)
echo_service = EchoServerImpl.new
server_runner = ServerRunner.new(echo_service)
server_port = server_runner.run
STDERR.puts 'start client'
control_stub, client_pid = start_client('sig_handling_client.rb', server_port)
client_started_mu.synchronize do
client_started_cv.wait(client_started_mu) until client_started
end
# use receipt of one RPC to indicate that the child process is
# ready
echo_service.wait_for_first_rpc_received(20)
count = 0
while count < 5
control_stub.do_echo_rpc(
@ -64,7 +37,6 @@ def main
Process.kill('SIGINT', client_pid)
count += 1
end
cleanup(control_stub, client_pid, server_runner)
end

@ -34,6 +34,16 @@ def main
trap('SIGINT') { exit 0 }
STDERR.puts 'sig_int_during_channel_watch_client.rb: SIGINT trap has been set'
# First, notify the parent process that we're ready for a SIGINT by sending
# an RPC
begin
stub = Echo::EchoServer::Stub.new(
"localhost:#{server_port}", :this_channel_is_insecure)
stub.echo(ClientControl::DoEchoRpcRequest.new)
rescue => e
fail "received error:|#{e}| while sending an RPC to the parent process " \
'to indicate that the SIGINT trap has been set'
end
thd = Thread.new do
child_thread_channel = GRPC::Core::Channel.new("localhost:#{server_port}",

@ -21,16 +21,19 @@ require_relative './end2end_common'
def main
STDERR.puts 'start server'
server_runner = ServerRunner.new(EchoServerImpl)
echo_service = EchoServerImpl.new
server_runner = ServerRunner.new(echo_service)
server_port = server_runner.run
STDERR.puts 'start client'
_, client_pid = start_client('sig_int_during_channel_watch_client.rb',
server_port)
# use receipt of one RPC to indicate that the child process is
# ready for a SIGINT
echo_service.wait_for_first_rpc_received(20)
# give time for the client to get into the middle
# of a channel state watch call
sleep 1
Process.kill('SIGINT', client_pid)
begin
Timeout.timeout(10) do
Process.wait(client_pid)
@ -43,12 +46,10 @@ def main
raise 'Timed out waiting for client process. It likely hangs when a ' \
'SIGINT is sent while there is an active connectivity_state call'
end
client_exit_code = $CHILD_STATUS
if client_exit_code != 0
fail "sig_int_during_channel_watch_client failed: #{client_exit_code}"
end
server_runner.stop
end

@ -246,8 +246,8 @@ TEST(CachingByteStream, SharedCache) {
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int retval = RUN_ALL_TESTS();
grpc_shutdown();

@ -233,8 +233,8 @@ TEST(StateTracker, DoNotNotifyShutdownAtDestructionIfAlreadyInShutdown) {
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc_init();
grpc_core::testing::grpc_tracer_enable_flag(
&grpc_core::grpc_connectivity_state_trace);

@ -42,9 +42,9 @@ TEST(StaticMetadataTest, ReadAllStaticElements) {
} // namespace grpc_core
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc_init();
grpc::testing::TestEnvironment env(argc, argv);
int retval = RUN_ALL_TESTS();
grpc_shutdown();
return retval;

@ -162,8 +162,6 @@ static void test_http2_status_to_grpc_status() {
}
int main(int argc, char** argv) {
int i;
grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
@ -173,7 +171,7 @@ int main(int argc, char** argv) {
test_http2_status_to_grpc_status();
/* check all status values can be converted */
for (i = 0; i <= 999; i++) {
for (int i = 0; i <= 999; i++) {
grpc_http2_status_to_grpc_status(i);
}

@ -17,11 +17,11 @@
*/
#include "src/core/lib/transport/status_metadata.h"
#include "src/core/lib/transport/static_metadata.h"
#include "test/core/util/test_config.h"
#include <gtest/gtest.h>
#include "src/core/lib/transport/static_metadata.h"
namespace {
TEST(GetStatusCodeFromMetadata, OK) {
@ -56,6 +56,7 @@ TEST(GetStatusCodeFromMetadata, Unparseable) {
} // namespace
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int ret = RUN_ALL_TESTS();

@ -56,17 +56,28 @@ _TEST_CASES = [
'secondary_locality_gets_requests_on_primary_failure',
'traffic_splitting',
]
# Valid test cases, but not in all. So the tests can only run manually, and
# aren't enabled automatically for all languages.
#
# TODO: Move them into _TEST_CASES when support is ready in all languages.
_ADDITIONAL_TEST_CASES = ['path_matching', 'header_matching']
def parse_test_cases(arg):
if arg == 'all':
return _TEST_CASES
if arg == '':
return []
test_cases = arg.split(',')
if all([test_case in _TEST_CASES for test_case in test_cases]):
return test_cases
raise Exception('Failed to parse test cases %s' % arg)
arg_split = arg.split(',')
test_cases = set()
all_test_cases = _TEST_CASES + _ADDITIONAL_TEST_CASES
for arg in arg_split:
if arg == "all":
test_cases = test_cases.union(_TEST_CASES)
else:
test_cases = test_cases.union([arg])
if not all([test_case in all_test_cases for test_case in test_cases]):
raise Exception('Failed to parse test cases %s' % arg)
# Perserve order.
return [x for x in all_test_cases if x in test_cases]
def parse_port_range(port_arg):
@ -89,8 +100,10 @@ argp.add_argument(
'--test_case',
default='ping_pong',
type=parse_test_cases,
help='Comma-separated list of test cases to run, or \'all\' to run every '
'test. Available tests: %s' % ' '.join(_TEST_CASES))
help='Comma-separated list of test cases to run. Available tests: %s, '
'(or \'all\' to run every test). '
'Alternative tests not included in \'all\': %s' %
(','.join(_TEST_CASES), ','.join(_ADDITIONAL_TEST_CASES)))
argp.add_argument(
'--bootstrap_file',
default='',
@ -237,6 +250,12 @@ _BOOTSTRAP_TEMPLATE = """
_TESTS_TO_FAIL_ON_RPC_FAILURE = [
'new_instance_group_receives_traffic', 'ping_pong', 'round_robin'
]
# Tests that run UnaryCall and EmptyCall.
_TESTS_TO_RUN_MULTIPLE_RPCS = ['path_matching', 'header_matching']
# Tests that make UnaryCall with test metadata.
_TESTS_TO_SEND_METADATA = ['header_matching']
_TEST_METADATA_KEY = 'xds_md'
_TEST_METADATA_VALUE = 'exact_match'
_PATH_MATCHER_NAME = 'path-matcher'
_BASE_TEMPLATE_NAME = 'test-template'
_BASE_INSTANCE_GROUP_NAME = 'test-ig'
@ -348,6 +367,29 @@ def compare_distributions(actual_distribution, expected_distribution,
return True
def compare_expected_instances(stats, expected_instances):
"""Compare if stats have expected instances for each type of RPC.
Args:
stats: LoadBalancerStatsResponse reported by interop client.
expected_instances: a dict with key as the RPC type (string), value as
the expected backend instances (list of strings).
Returns:
Returns true if the instances are expected. False if not.
"""
for rpc_type, expected_peers in expected_instances.items():
rpcs_by_peer_for_type = stats.rpcs_by_method[rpc_type]
rpcs_by_peer = rpcs_by_peer_for_type.rpcs_by_peer if rpcs_by_peer_for_type else None
logger.debug('rpc: %s, by_peer: %s', rpc_type, rpcs_by_peer)
peers = list(rpcs_by_peer.keys())
if set(peers) != set(expected_peers):
logger.info('unexpected peers for %s, got %s, want %s', rpc_type,
peers, expected_peers)
return False
return True
def test_backends_restart(gcp, backend_service, instance_group):
logger.info('Running test_backends_restart')
instance_names = get_instance_names(gcp, instance_group)
@ -629,19 +671,20 @@ def test_secondary_locality_gets_requests_on_primary_failure(
patch_backend_instances(gcp, backend_service, [primary_instance_group])
def test_traffic_splitting(gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group):
# This test start with all traffic going to original_backend_service. Then
# it updates URL-map to set default action to traffic splitting between
# original and alternate. It waits for all backends in both services to
# receive traffic, then verifies that weights are expected.
logger.info('Running test_traffic_splitting')
def prepare_services_for_urlmap_tests(gcp, original_backend_service,
instance_group, alternate_backend_service,
same_zone_instance_group):
'''
This function prepares the services to be ready for tests that modifies
urlmaps.
Returns:
Returns original and alternate backend names as lists of strings.
'''
# The config validation for proxyless doesn't allow setting
# default_route_action. To test traffic splitting, we need to set the
# route action to weighted clusters. Disable validate
# validate_for_proxyless for this test. This can be removed when
# validation accepts default_route_action.
# default_route_action or route_rules. Disable validate
# validate_for_proxyless for this test. This can be removed when validation
# accepts default_route_action.
logger.info('disabling validate_for_proxyless in target proxy')
set_validate_for_proxyless(gcp, False)
@ -665,6 +708,20 @@ def test_traffic_splitting(gcp, original_backend_service, instance_group,
logger.info('waiting for traffic to all go to original backends')
wait_until_all_rpcs_go_to_given_backends(original_backend_instances,
_WAIT_FOR_STATS_SEC)
return original_backend_instances, alternate_backend_instances
def test_traffic_splitting(gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group):
# This test start with all traffic going to original_backend_service. Then
# it updates URL-map to set default action to traffic splitting between
# original and alternate. It waits for all backends in both services to
# receive traffic, then verifies that weights are expected.
logger.info('Running test_traffic_splitting')
original_backend_instances, alternate_backend_instances = prepare_services_for_urlmap_tests(
gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group)
try:
# Patch urlmap, change route action to traffic splitting between
@ -728,6 +785,157 @@ def test_traffic_splitting(gcp, original_backend_service, instance_group,
set_validate_for_proxyless(gcp, True)
def test_path_matching(gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group):
# This test start with all traffic (UnaryCall and EmptyCall) going to
# original_backend_service.
#
# Then it updates URL-map to add routes, to make UnaryCall and EmptyCall to
# go different backends. It waits for all backends in both services to
# receive traffic, then verifies that traffic goes to the expected
# backends.
logger.info('Running test_path_matching')
original_backend_instances, alternate_backend_instances = prepare_services_for_urlmap_tests(
gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group)
try:
# A list of tuples (route_rules, expected_instances).
test_cases = [
(
[{
'priority': 0,
# FullPath EmptyCall -> alternate_backend_service.
'matchRules': [{
'fullPathMatch': '/grpc.testing.TestService/EmptyCall'
}],
'service': alternate_backend_service.url
}],
{
"EmptyCall": alternate_backend_instances,
"UnaryCall": original_backend_instances
}),
(
[{
'priority': 0,
# Prefix UnaryCall -> alternate_backend_service.
'matchRules': [{
'prefixMatch': '/grpc.testing.TestService/Unary'
}],
'service': alternate_backend_service.url
}],
{
"UnaryCall": alternate_backend_instances,
"EmptyCall": original_backend_instances
})
]
for (route_rules, expected_instances) in test_cases:
logger.info('patching url map with %s -> alternative',
route_rules[0]['matchRules'])
patch_url_map_backend_service(gcp,
original_backend_service,
route_rules=route_rules)
# Wait for traffic to go to both services.
logger.info(
'waiting for traffic to go to all backends (including alternate)'
)
wait_until_all_rpcs_go_to_given_backends(
original_backend_instances + alternate_backend_instances,
_WAIT_FOR_STATS_SEC)
retry_count = 10
# Each attempt takes about 10 seconds, 10 retries is equivalent to 100
# seconds timeout.
for i in range(retry_count):
stats = get_client_stats(_NUM_TEST_RPCS, _WAIT_FOR_STATS_SEC)
if not stats.rpcs_by_method:
raise ValueError(
'stats.rpcs_by_method is None, the interop client stats service does not support this test case'
)
logger.info('attempt %d', i)
if compare_expected_instances(stats, expected_instances):
logger.info("success")
break
finally:
patch_url_map_backend_service(gcp, original_backend_service)
patch_backend_instances(gcp, alternate_backend_service, [])
set_validate_for_proxyless(gcp, True)
def test_header_matching(gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group):
# This test start with all traffic (UnaryCall and EmptyCall) going to
# original_backend_service.
#
# Then it updates URL-map to add routes, to make RPCs with test headers to
# go to different backends. It waits for all backends in both services to
# receive traffic, then verifies that traffic goes to the expected
# backends.
logger.info('Running test_header_matching')
original_backend_instances, alternate_backend_instances = prepare_services_for_urlmap_tests(
gcp, original_backend_service, instance_group,
alternate_backend_service, same_zone_instance_group)
try:
# A list of tuples (route_rules, expected_instances).
test_cases = [(
[{
'priority': 0,
# Header ExactMatch -> alternate_backend_service.
# EmptyCall is sent with the metadata.
'matchRules': [{
'prefixMatch':
'/',
'headerMatches': [{
'headerName': _TEST_METADATA_KEY,
'exactMatch': _TEST_METADATA_VALUE
}]
}],
'service': alternate_backend_service.url
}],
{
"EmptyCall": alternate_backend_instances,
"UnaryCall": original_backend_instances
})]
for (route_rules, expected_instances) in test_cases:
logger.info('patching url map with %s -> alternative',
route_rules[0]['matchRules'])
patch_url_map_backend_service(gcp,
original_backend_service,
route_rules=route_rules)
# Wait for traffic to go to both services.
logger.info(
'waiting for traffic to go to all backends (including alternate)'
)
wait_until_all_rpcs_go_to_given_backends(
original_backend_instances + alternate_backend_instances,
_WAIT_FOR_STATS_SEC)
retry_count = 10
# Each attempt takes about 10 seconds, 10 retries is equivalent to 100
# seconds timeout.
for i in range(retry_count):
stats = get_client_stats(_NUM_TEST_RPCS, _WAIT_FOR_STATS_SEC)
if not stats.rpcs_by_method:
raise ValueError(
'stats.rpcs_by_method is None, the interop client stats service does not support this test case'
)
logger.info('attempt %d', i)
if compare_expected_instances(stats, expected_instances):
logger.info("success")
break
finally:
patch_url_map_backend_service(gcp, original_backend_service)
patch_backend_instances(gcp, alternate_backend_service, [])
set_validate_for_proxyless(gcp, True)
def set_serving_status(instances, service_port, serving):
for instance in instances:
with grpc.insecure_channel('%s:%d' %
@ -1208,7 +1416,8 @@ def resize_instance_group(gcp,
def patch_url_map_backend_service(gcp,
backend_service=None,
services_with_weights=None):
services_with_weights=None,
route_rules=None):
'''change url_map's backend service
Only one of backend_service and service_with_weights can be not None.
@ -1230,6 +1439,7 @@ def patch_url_map_backend_service(gcp,
'name': _PATH_MATCHER_NAME,
'defaultService': default_service,
'defaultRouteAction': default_route_action,
'routeRules': route_rules,
}]
}
logger.debug('Sending GCP request with body=%s', config)
@ -1495,15 +1705,32 @@ try:
test_log_filename = os.path.join(log_dir, _SPONGE_LOG_NAME)
test_log_file = open(test_log_filename, 'w+')
client_process = None
if test_case in _TESTS_TO_RUN_MULTIPLE_RPCS:
rpcs_to_send = '--rpc="UnaryCall,EmptyCall"'
else:
rpcs_to_send = '--rpc="UnaryCall"'
if test_case in _TESTS_TO_SEND_METADATA:
metadata_to_send = '--metadata="EmptyCall:{key}:{value}"'.format(
key=_TEST_METADATA_KEY, value=_TEST_METADATA_VALUE)
else:
metadata_to_send = '--metadata=""'
if test_case in _TESTS_TO_FAIL_ON_RPC_FAILURE:
fail_on_failed_rpc = '--fail_on_failed_rpc=true'
else:
fail_on_failed_rpc = '--fail_on_failed_rpc=false'
client_cmd = shlex.split(
args.client_cmd.format(server_uri=server_uri,
stats_port=args.stats_port,
qps=args.qps,
fail_on_failed_rpc=fail_on_failed_rpc))
client_cmd_formatted = args.client_cmd.format(
server_uri=server_uri,
stats_port=args.stats_port,
qps=args.qps,
fail_on_failed_rpc=fail_on_failed_rpc,
rpcs_to_send=rpcs_to_send,
metadata_to_send=metadata_to_send)
logger.debug('running client: %s', client_cmd_formatted)
client_cmd = shlex.split(client_cmd_formatted)
try:
client_process = subprocess.Popen(client_cmd,
env=client_env,
@ -1543,6 +1770,14 @@ try:
test_traffic_splitting(gcp, backend_service, instance_group,
alternate_backend_service,
same_zone_instance_group)
elif test_case == 'path_matching':
test_path_matching(gcp, backend_service, instance_group,
alternate_backend_service,
same_zone_instance_group)
elif test_case == 'header_matching':
test_header_matching(gcp, backend_service, instance_group,
alternate_backend_service,
same_zone_instance_group)
else:
logger.error('Unknown test case: %s', test_case)
sys.exit(1)

Loading…
Cancel
Save