diff --git a/CMakeLists.txt b/CMakeLists.txt index a6ea748ba3d..47d8b3c6d0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -725,6 +725,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx writes_per_rpc_test) endif() add_dependencies(buildtests_cxx xds_end2end_test) +add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test) add_dependencies(buildtests_cxx badreq_bad_client_test) add_dependencies(buildtests_cxx connection_prefix_bad_client_test) add_dependencies(buildtests_cxx duplicate_header_bad_client_test) @@ -732,6 +733,7 @@ add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test) add_dependencies(buildtests_cxx headers_bad_client_test) add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test) add_dependencies(buildtests_cxx large_metadata_bad_client_test) +add_dependencies(buildtests_cxx out_of_bounds_bad_client_test) add_dependencies(buildtests_cxx server_registered_method_bad_client_test) add_dependencies(buildtests_cxx simple_request_bad_client_test) add_dependencies(buildtests_cxx unknown_frame_bad_client_test) @@ -17077,6 +17079,46 @@ target_link_libraries(gen_percent_encoding_tables if (gRPC_BUILD_TESTS) +add_executable(bad_streaming_id_bad_client_test + test/core/bad_client/tests/bad_streaming_id.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bad_streaming_id_bad_client_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bad_streaming_id_bad_client_test + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + bad_client_test + grpc_test_util_unsecure + grpc_unsecure + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(badreq_bad_client_test test/core/bad_client/tests/badreq.cc third_party/googletest/googletest/src/gtest-all.cc @@ -17354,6 +17396,46 @@ target_link_libraries(large_metadata_bad_client_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(out_of_bounds_bad_client_test + test/core/bad_client/tests/out_of_bounds.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(out_of_bounds_bad_client_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(out_of_bounds_bad_client_test + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + bad_client_test + grpc_test_util_unsecure + grpc_unsecure + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 2eca2bddd60..6bcf8472d3e 100644 --- a/Makefile +++ b/Makefile @@ -1292,6 +1292,7 @@ gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test +bad_streaming_id_bad_client_test: $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test @@ -1299,6 +1300,7 @@ head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test large_metadata_bad_client_test: $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test +out_of_bounds_bad_client_test: $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test simple_request_bad_client_test: $(BINDIR)/$(CONFIG)/simple_request_bad_client_test unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test @@ -1753,6 +1755,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/boringssl_ssl_test \ $(BINDIR)/$(CONFIG)/boringssl_crypto_test \ + $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ @@ -1760,6 +1763,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/headers_bad_client_test \ $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ + $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \ $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ @@ -1913,6 +1917,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ + $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ @@ -1920,6 +1925,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/headers_bad_client_test \ $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ + $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \ $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ @@ -2446,6 +2452,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) $(E) "[RUN] Testing xds_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing bad_streaming_id_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test || ( echo test bad_streaming_id_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing connection_prefix_bad_client_test" @@ -2460,6 +2468,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing large_metadata_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing out_of_bounds_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test || ( echo test out_of_bounds_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing server_registered_method_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing simple_request_bad_client_test" @@ -20377,6 +20387,37 @@ ifneq ($(NO_DEPS),true) endif +BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC = \ + test/core/bad_client/tests/bad_streaming_id.cc \ + +BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC)))) + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: $(PROTOBUF_DEP) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/bad_streaming_id.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_bad_streaming_id_bad_client_test: $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep) +endif + + BADREQ_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/badreq.cc \ @@ -20594,6 +20635,37 @@ ifneq ($(NO_DEPS),true) endif +OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC = \ + test/core/bad_client/tests/out_of_bounds.cc \ + +OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC)))) + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: $(PROTOBUF_DEP) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/out_of_bounds.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_out_of_bounds_bad_client_test: $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep) +endif + + SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/server_registered_method.cc \ diff --git a/Rakefile b/Rakefile index d604f7935b1..8123dc541dc 100755 --- a/Rakefile +++ b/Rakefile @@ -124,10 +124,10 @@ task 'gem:native' do "invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \ "build should be running on ruby 2.5." end - system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" else Rake::Task['dlls'].execute - docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" end end diff --git a/grpc.gemspec b/grpc.gemspec index 65cc9a54f2c..2be38bb3b43 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.description = 'Send RPCs from Ruby using GRPC' s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.0.0' + s.required_ruby_version = '>= 2.3.0' s.files = %w( Makefile .yardopts ) s.files += %w( etc/roots.pem ) diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 00036d8be64..e0deed27442 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -128,6 +128,10 @@ class PickFirst : public LoadBalancingPolicy { void ShutdownLocked() override; + void AttemptToConnectUsingLatestUpdateArgsLocked(); + + // Lateset update args. + UpdateArgs latest_update_args_; // All our subchannels. OrphanablePtr subchannel_list_; // Latest pending subchannel list. @@ -167,18 +171,7 @@ void PickFirst::ExitIdleLocked() { if (shutdown_) return; if (idle_) { idle_ = false; - if (subchannel_list_ == nullptr || - subchannel_list_->num_subchannels() == 0) { - grpc_error* error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - UniquePtr(New(error))); - } else { - subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); - } + AttemptToConnectUsingLatestUpdateArgsLocked(); } } @@ -189,36 +182,26 @@ void PickFirst::ResetBackoffLocked() { } } -void PickFirst::UpdateLocked(UpdateArgs args) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { - gpr_log(GPR_INFO, - "Pick First %p received update with %" PRIuPTR " addresses", this, - args.addresses.size()); - } - grpc_arg new_arg = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(args.args, &new_arg, 1); +void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() { + // Create a subchannel list from the latest_update_args_. auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); - grpc_channel_args_destroy(new_args); + this, &grpc_lb_pick_first_trace, latest_update_args_.addresses, + combiner(), *latest_update_args_.args); + // Empty update or no valid subchannels. if (subchannel_list->num_subchannels() == 0) { - // Empty update or no valid subchannels. Unsubscribe from all current - // subchannels. + // Unsubscribe from all current subchannels. subchannel_list_ = std::move(subchannel_list); // Empty list. selected_ = nullptr; // If not idle, put the channel in TRANSIENT_FAILURE. // (If we are idle, then this will happen in ExitIdleLocked() if we // haven't gotten a non-empty update by the time the application tries // to start a new call.) - if (!idle_) { - grpc_error* error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - UniquePtr(New(error))); - } + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); return; } // If one of the subchannels in the new list is already in state @@ -226,8 +209,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // currently selected subchannel is also present in the update. It // can also happen if one of the subchannels in the update is already // in the global subchannel pool because it's in use by another channel. - // TODO(roth): If we're in IDLE state, we should probably defer this - // check and instead do it in ExitIdleLocked(). for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { PickFirstSubchannelData* sd = subchannel_list->subchannel(i); grpc_connectivity_state state = sd->CheckConnectivityStateLocked(); @@ -239,10 +220,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // not have contained the currently selected subchannel), drop // it, so that it doesn't override what we've done here. latest_pending_subchannel_list_.reset(); - // Make sure that subsequent calls to ExitIdleLocked() don't cause - // us to start watching a subchannel other than the one we've - // selected. - idle_ = false; return; } } @@ -252,13 +229,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) { subchannel_list_ = std::move(subchannel_list); // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (!idle_) { - // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() - // here, since we've already checked the initial connectivity - // state of all subchannels above. - subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); - subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect(); - } + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. + subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect(); } else { // We do have a selected subchannel (which means it's READY), so keep // using it until one of the subchannels in the new list reports READY. @@ -274,16 +249,35 @@ void PickFirst::UpdateLocked(UpdateArgs args) { latest_pending_subchannel_list_ = std::move(subchannel_list); // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (!idle_) { - // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() - // here, since we've already checked the initial connectivity - // state of all subchannels above. - latest_pending_subchannel_list_->subchannel(0) - ->StartConnectivityWatchLocked(); - latest_pending_subchannel_list_->subchannel(0) - ->subchannel() - ->AttemptToConnect(); - } + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. + latest_pending_subchannel_list_->subchannel(0) + ->StartConnectivityWatchLocked(); + latest_pending_subchannel_list_->subchannel(0) + ->subchannel() + ->AttemptToConnect(); + } +} + +void PickFirst::UpdateLocked(UpdateArgs args) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, + "Pick First %p received update with %" PRIuPTR " addresses", this, + args.addresses.size()); + } + // Update the latest_update_args_ + grpc_arg new_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + const grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args.args, &new_arg, 1); + GPR_SWAP(const grpc_channel_args*, new_args, args.args); + grpc_channel_args_destroy(new_args); + latest_update_args_ = std::move(args); + // If we are not in idle, start connection attempt immediately. + // Otherwise, we defer the attempt into ExitIdleLocked(). + if (!idle_) { + AttemptToConnectUsingLatestUpdateArgsLocked(); } } @@ -338,10 +332,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // also set the channel state to IDLE. The reason is that if the new // state is TRANSIENT_FAILURE due to a GOAWAY reception we don't want // to connect to the re-resolved backends until we leave IDLE state. + // TODO(qianchengz): We may want to request re-resolution in + // ExitIdleLocked(). p->idle_ = true; p->channel_control_helper()->RequestReresolution(); p->selected_ = nullptr; - CancelConnectivityWatchLocked("selected subchannel failed; going IDLE"); + p->subchannel_list_.reset(); p->channel_control_helper()->UpdateState( GRPC_CHANNEL_IDLE, UniquePtr(New( p->Ref(DEBUG_LOCATION, "QueuePicker")))); @@ -454,6 +450,11 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } + for (size_t i = 0; i < subchannel_list()->num_subchannels(); ++i) { + if (i != Index()) { + subchannel_list()->subchannel(i)->ShutdownLocked(); + } + } } void PickFirst::PickFirstSubchannelData:: diff --git a/src/objective-c/tests/UnitTests/GRPCClientTests.m b/src/objective-c/tests/UnitTests/GRPCClientTests.m index 94164164c28..bcd87c17b78 100644 --- a/src/objective-c/tests/UnitTests/GRPCClientTests.m +++ b/src/objective-c/tests/UnitTests/GRPCClientTests.m @@ -37,10 +37,14 @@ #define TEST_TIMEOUT 16 -static NSString *const kHostAddress = @"localhost:5050"; +// 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 kHostAddress = NSStringize(HOST_PORT_LOCAL); static NSString *const kPackage = @"grpc.testing"; static NSString *const kService = @"TestService"; -static NSString *const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com"; +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); static GRPCProtoMethod *kInexistentMethod; static GRPCProtoMethod *kEmptyCallMethod; diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh old mode 100644 new mode 100755 index 04cba0e321a..b74107e4a66 --- a/src/objective-c/tests/run_one_test.sh +++ b/src/objective-c/tests/run_one_test.sh @@ -45,10 +45,18 @@ set -o pipefail XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )' +if [ -z $PLATFORM ]; then +DESTINATION='name=iPhone 8' +elif [ $PLATFORM == ios ]; then +DESTINATION='name=iPhone 8' +elif [ $PLATFORM == macos ]; then +DESTINATION='platform=macOS' +fi + xcodebuild \ -workspace Tests.xcworkspace \ - -scheme SCHEME \ - -destination name="iPhone 8" \ + -scheme $SCHEME \ + -destination "$DESTINATION" \ HOST_PORT_LOCALSSL=localhost:$TLS_PORT \ HOST_PORT_LOCAL=localhost:$PLAIN_PORT \ HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index f8dd0938936..12862c82b29 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -15,7 +15,7 @@ s.description = 'Send RPCs from Ruby using GRPC' s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.0.0' + s.required_ruby_version = '>= 2.3.0' s.files = %w( Makefile .yardopts ) s.files += %w( etc/roots.pem ) diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index a4f3e4a0a34..e390db90e15 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -27,12 +27,14 @@ default_test_options = TestOptions(False, 1.0) # maps test names to options BAD_CLIENT_TESTS = { 'badreq': default_test_options, + 'bad_streaming_id': default_test_options, 'connection_prefix': default_test_options._replace(cpu_cost=0.2), 'duplicate_header': default_test_options, 'headers': default_test_options._replace(cpu_cost=0.2), 'initial_settings_frame': default_test_options._replace(cpu_cost=0.2), 'head_of_line_blocking': default_test_options, 'large_metadata': default_test_options, + 'out_of_bounds': default_test_options, 'server_registered_method': default_test_options, 'simple_request': default_test_options, 'window_overflow': default_test_options, diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index da372dd0bc9..6fb53eeffe1 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -25,12 +25,14 @@ def test_options(): # maps test names to options BAD_CLIENT_TESTS = { 'badreq': test_options(), + 'bad_streaming_id': test_options(), 'connection_prefix': test_options(), 'duplicate_header': test_options(), 'headers': test_options(), 'initial_settings_frame': test_options(), 'head_of_line_blocking': test_options(), 'large_metadata': test_options(), + 'out_of_bounds': test_options(), 'server_registered_method': test_options(), 'simple_request': test_options(), 'window_overflow': test_options(), diff --git a/test/core/bad_client/tests/bad_streaming_id.cc b/test/core/bad_client/tests/bad_streaming_id.cc new file mode 100644 index 00000000000..287db433880 --- /dev/null +++ b/test/core/bad_client/tests/bad_streaming_id.cc @@ -0,0 +1,132 @@ +/* + * + * 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. + * + */ + +#include + +#include + +#include +#include "src/core/lib/surface/server.h" +#include "test/core/bad_client/bad_client.h" + +#define HEADER_FRAME_ID_1 \ + "\x00\x00\xc9\x01\x05\x00\x00\x00\x01" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +#define HEADER_FRAME_ID_2 \ + "\x00\x00\xc9\x01\x05\x00\x00\x00\x02" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +#define HEADER_FRAME_ID_3 \ + "\x00\x00\xc9\x01\x05\x00\x00\x00\x03" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +namespace { + +void verifier(grpc_server* server, grpc_completion_queue* cq, + void* registered_method) { + while (grpc_server_has_open_connections(server)) { + GPR_ASSERT(grpc_completion_queue_next( + cq, grpc_timeout_milliseconds_to_deadline(20), nullptr) + .type == GRPC_QUEUE_TIMEOUT); + } +} + +TEST(BadStreamingId, RegularHeader) { + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + args[1].client_validator = nullptr; + args[1].client_payload = HEADER_FRAME_ID_1; + args[1].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1; + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); +} + +TEST(BadStreamingId, NonClientStreamId) { + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + // send a header frame with non-client stream id 2 + args[1].client_validator = nullptr; + args[1].client_payload = HEADER_FRAME_ID_2; + args[1].client_payload_length = sizeof(HEADER_FRAME_ID_2) - 1; + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); +} + +TEST(BadStreamingId, ClosedStreamId) { + grpc_bad_client_arg args[4]; + args[0] = connection_preface_arg; + // send a header frame with stream id 1 + args[1].client_validator = nullptr; + args[1].client_payload = HEADER_FRAME_ID_1; + args[1].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1; + // send a header frame with stream id 3 + args[2].client_validator = nullptr; + args[2].client_payload = HEADER_FRAME_ID_3; + args[2].client_payload_length = sizeof(HEADER_FRAME_ID_3) - 1; + // send a header frame with closed stream id 1 again + args[3].client_validator = nullptr; + args[3].client_payload = HEADER_FRAME_ID_1; + args[3].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1; + grpc_run_bad_client_test(verifier, args, 4, GRPC_BAD_CLIENT_DISCONNECT); +} + +} // namespace + +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + int retval = RUN_ALL_TESTS(); + grpc_shutdown(); + return retval; +} diff --git a/test/core/bad_client/tests/out_of_bounds.cc b/test/core/bad_client/tests/out_of_bounds.cc new file mode 100644 index 00000000000..b716e952bc1 --- /dev/null +++ b/test/core/bad_client/tests/out_of_bounds.cc @@ -0,0 +1,112 @@ +/* + * + * 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. + * + */ + +#include + +#include + +#include +#include "src/core/lib/surface/server.h" +#include "test/core/bad_client/bad_client.h" + +#define APPEND_BUFFER(string, to_append) \ + ((string).append((to_append), sizeof(to_append) - 1)) + +namespace { + +void verifier(grpc_server* server, grpc_completion_queue* cq, + void* registered_method) { + while (grpc_server_has_open_connections(server)) { + GPR_ASSERT(grpc_completion_queue_next( + cq, grpc_timeout_milliseconds_to_deadline(20), nullptr) + .type == GRPC_QUEUE_TIMEOUT); + } +} + +void FrameVerifier(const std::string& attack_vector) { + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + args[1].client_validator = nullptr; + args[1].client_payload = attack_vector.c_str(); + args[1].client_payload_length = attack_vector.size(); + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); +} + +TEST(OutOfBounds, MaxFrameSizeDataFrame) { + std::string out_of_bounds_data; + // Send a data frame larger than 2^14 + APPEND_BUFFER(out_of_bounds_data, "\x01\x00\x00\x00\x00\x00\x00\x00\x01"); + out_of_bounds_data.append(1 << 16, 'a'); + FrameVerifier(out_of_bounds_data); +} + +TEST(OutOfBounds, BadSizePriorityFrame) { + std::string bad_size_priority_frame; + // Priority Frame should be a length of 5 octets + APPEND_BUFFER(bad_size_priority_frame, + "\x00\x00\x03\x02\x00\x00\x00\x00\x01" + "\x11\x11\x12"); + FrameVerifier(bad_size_priority_frame); +} + +TEST(OutOfBounds, BadSizeRstStream) { + std::string bad_size_rst_stream; + // Rst Stream Frame should have a length of 4 octets + APPEND_BUFFER(bad_size_rst_stream, + "\x00\x00\x02\x03\x00\x00\x00\x00\x01" + "\x11\x11"); + FrameVerifier(bad_size_rst_stream); +} + +TEST(OutOfBounds, BadSizeSettings) { + std::string bad_size_settings; + // Settings Frame should have a length which is a multiple of 6 octets + APPEND_BUFFER(bad_size_settings, + "\x00\x00\x05\x04\x00\x00\x00\x00\x00" + "\x11\x11\x11\x11\x11"); + FrameVerifier(bad_size_settings); +} + +TEST(OutOfBounds, BadSizePing) { + std::string bad_size_ping; + // Rst Stream Frame should have a length of 8 octets + APPEND_BUFFER(bad_size_ping, + "\x00\x00\x05\x06\x00\x00\x00\x00\x00" + "\x11\x11\x11\x11\x11"); + FrameVerifier(bad_size_ping); +} + +TEST(OutOfBounds, WindowUpdate) { + std::string bad_size_window_update; + // Window Update Frame should have a length of 4 octets + APPEND_BUFFER(bad_size_window_update, + "\x00\x00\x01\x08\x00\x00\x00\x00\x00" + "\x11"); + FrameVerifier(bad_size_window_update); +} + +} // namespace + +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + int retval = RUN_ALL_TESTS(); + grpc_shutdown(); + return retval; +} diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index b53ffc22d4f..0812b860d7f 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -22,14 +22,14 @@ RUN yum install -y tar which RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 +# Install Ruby 2.3 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8") +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index 72235bfba7f..fc4eabbbb15 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -20,12 +20,12 @@ RUN yum update && yum install -y curl tar which RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index 3d688a889f0..73a4bd76c88 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -21,14 +21,14 @@ RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y opens RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 +# Install Ruby 2.3 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8") +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index 8044adf15dc..43c0ae5d8d6 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -26,12 +26,12 @@ RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y opens RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile index 848c5be789a..e077f68a38d 100644 --- a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile @@ -14,6 +14,26 @@ FROM fedora:22 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# Make yum work properly under docker when using overlay storage driver. +# https://bugzilla.redhat.com/show_bug.cgi?id=1213602#c9 +# https://github.com/docker/docker/issues/10180 +RUN yum install -y yum-plugin-ovl -RUN gem install bundler +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar procps + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile index 47dd577e217..f586ae377a3 100644 --- a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile @@ -14,6 +14,26 @@ FROM fedora:23 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# Make yum work properly under docker when using overlay storage driver. +# https://bugzilla.redhat.com/show_bug.cgi?id=1213602#c9 +# https://github.com/docker/docker/issues/10180 +RUN yum install -y yum-plugin-ovl -RUN gem install bundler +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar procps + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile deleted file mode 100644 index 337fc3b5d8e..00000000000 --- a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 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. - -FROM debian:jessie - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - curl \ - gcc && apt-get clean - -#================== -# Ruby dependencies - -# Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB -RUN \curl -sSL https://get.rvm.io | bash -s stable - -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" -RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" -RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index 1e861029faa..35a561ea928 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -340,14 +340,12 @@ def targets(): RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), - # TODO(apolcyn): unskip these after upgrading the ruby versions - # of these dockerfiles to >= 2.3. - # RubyDistribTest('linux', 'x64', 'centos6'), - # RubyDistribTest('linux', 'x64', 'centos7'), - # RubyDistribTest('linux', 'x64', 'fedora20'), - # RubyDistribTest('linux', 'x64', 'fedora21'), - # RubyDistribTest('linux', 'x64', 'fedora22'), - # RubyDistribTest('linux', 'x64', 'fedora23'), + RubyDistribTest('linux', 'x64', 'centos6'), + RubyDistribTest('linux', 'x64', 'centos7'), + RubyDistribTest('linux', 'x64', 'fedora20'), + RubyDistribTest('linux', 'x64', 'fedora21'), + RubyDistribTest('linux', 'x64', 'fedora22'), + RubyDistribTest('linux', 'x64', 'fedora23'), RubyDistribTest('linux', 'x64', 'opensuse'), RubyDistribTest('linux', 'x64', 'ubuntu1204'), RubyDistribTest('linux', 'x64', 'ubuntu1404'), diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6a420677811..9bb1ddba930 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5285,6 +5285,23 @@ "third_party": true, "type": "target" }, + { + "deps": [ + "bad_client_test", + "gpr", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bad_streaming_id_bad_client_test", + "src": [ + "test/core/bad_client/tests/bad_streaming_id.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "bad_client_test", @@ -5404,6 +5421,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "bad_client_test", + "gpr", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "out_of_bounds_bad_client_test", + "src": [ + "test/core/bad_client/tests/out_of_bounds.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "bad_client_test", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 681d88fd483..29657db49f9 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5942,6 +5942,32 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bad_streaming_id_bad_client_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -6124,6 +6150,32 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "out_of_bounds_bad_client_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index e5506063091..f11927bd5d6 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1058,8 +1058,8 @@ class ObjCLanguage(object): def test_specs(self): out = [] - if self.config == 'dbg': - out += self.config.job_spec( + out.append( + self.config.job_spec( ['src/objective-c/tests/build_one_example.sh'], timeout_seconds=10 * 60, shortname='ios-buildtest-example-sample', @@ -1067,8 +1067,9 @@ class ObjCLanguage(object): environ={ 'SCHEME': 'Sample', 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' - }) - out += job_spec( + })) + out.append( + self.config.job_spec( ['src/objective-c/tests/build_one_example.sh'], timeout_seconds=10 * 60, shortname='ios-buildtest-example-sample-frameworks', @@ -1077,8 +1078,9 @@ class ObjCLanguage(object): 'SCHEME': 'Sample', 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', 'FRAMEWORKS': 'YES' - }) - out += self.config.job_spec( + })) + out.append( + self.config.job_spec( ['src/objective-c/tests/build_one_example.sh'], timeout_seconds=10 * 60, shortname='ios-buildtest-example-switftsample', @@ -1086,51 +1088,58 @@ class ObjCLanguage(object): environ={ 'SCHEME': 'SwiftSample', 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' - }) - out += self.config.job_spec( + })) + out.append( + self.config.job_spec( ['src/objective-c/tests/run_plugin_tests.sh'], timeout_seconds=60 * 60, shortname='ios-test-plugintest', cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( + environ=_FORCE_ENVIRON_FOR_WRAPPERS)) + out.append( + self.config.job_spec( ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], timeout_seconds=20 * 60, shortname='ios-test-cfstream-tests', cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( + environ=_FORCE_ENVIRON_FOR_WRAPPERS)) + out.append( + self.config.job_spec( ['src/objective-c/tests/run_one_test.sh'], timeout_seconds=60 * 60, shortname='ios-test-unittests', cpu_cost=1e6, environ={ - SCHEME: 'UnitTests' - }) - out += self.config.job_spec( + 'SCHEME': 'UnitTests' + })) + out.append( + self.config.job_spec( ['src/objective-c/tests/run_one_test.sh'], timeout_seconds=60 * 60, shortname='ios-test-interoptests', cpu_cost=1e6, environ={ - SCHEME: 'InteropTests' - }) - out += self.config.job_spec( + 'SCHEME': 'InteropTests' + })) + out.append( + self.config.job_spec( ['src/objective-c/tests/run_one_test.sh'], timeout_seconds=60 * 60, shortname='ios-test-cronettests', cpu_cost=1e6, environ={ - SCHEME: 'CronetTests' - }) - out += self.config.job_spec( + 'SCHEME': 'CronetTests' + })) + out.append( + self.config.job_spec( ['src/objective-c/tests/run_one_test.sh'], timeout_seconds=60 * 60, shortname='mac-test-basictests', cpu_cost=1e6, environ={ - SCHEME: 'MacTests' - }) + 'SCHEME': 'MacTests', + 'PLATFORM': 'macos' + })) return sorted(out)