diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ff9866d7d1..ea2cb5d10d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1167,7 +1167,6 @@ if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx posix_event_engine_test) endif() - add_dependencies(buildtests_cxx pre_stop_hook_server_test) add_dependencies(buildtests_cxx prioritized_race_test) add_dependencies(buildtests_cxx promise_endpoint_test) add_dependencies(buildtests_cxx promise_factory_test) @@ -17785,83 +17784,6 @@ endif() endif() if(gRPC_BUILD_TESTS) -add_executable(pre_stop_hook_server_test - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/istio_echo.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/istio_echo.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/istio_echo.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/istio_echo.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h - ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h - src/cpp/server/admin/admin_services.cc - src/cpp/server/csds/csds.cc - test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/interop/pre_stop_hook_server.cc - test/cpp/interop/pre_stop_hook_server_test.cc - test/cpp/interop/xds_interop_server_lib.cc -) -target_compile_features(pre_stop_hook_server_test PUBLIC cxx_std_14) -target_include_directories(pre_stop_hook_server_test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - ${_gRPC_RE2_INCLUDE_DIR} - ${_gRPC_SSL_INCLUDE_DIR} - ${_gRPC_UPB_GENERATED_DIR} - ${_gRPC_UPB_GRPC_GENERATED_DIR} - ${_gRPC_UPB_INCLUDE_DIR} - ${_gRPC_XXHASH_INCLUDE_DIR} - ${_gRPC_ZLIB_INCLUDE_DIR} - third_party/googletest/googletest/include - third_party/googletest/googletest - third_party/googletest/googlemock/include - third_party/googletest/googlemock - ${_gRPC_PROTO_GENS_DIR} -) - -target_link_libraries(pre_stop_hook_server_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gtest - grpc++_reflection - grpcpp_channelz - grpc_test_util - grpc++_test_config -) - - -endif() -if(gRPC_BUILD_TESTS) - add_executable(prioritized_race_test test/core/promise/prioritized_race_test.cc ) @@ -27588,7 +27510,6 @@ add_executable(xds_interop_server src/cpp/server/admin/admin_services.cc src/cpp/server/csds/csds.cc test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/interop/pre_stop_hook_server.cc test/cpp/interop/xds_interop_server.cc test/cpp/interop/xds_interop_server_lib.cc ) @@ -27660,7 +27581,6 @@ add_executable(xds_interop_server_test src/cpp/server/admin/admin_services.cc src/cpp/server/csds/csds.cc test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/interop/pre_stop_hook_server.cc test/cpp/interop/xds_interop_server_lib.cc test/cpp/interop/xds_interop_server_test.cc ) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index f74c2a16850..73c018b8fcd 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -12223,37 +12223,6 @@ targets: platforms: - linux - posix -- name: pre_stop_hook_server_test - gtest: true - build: test - language: c++ - headers: - - src/cpp/server/csds/csds.h - - test/cpp/end2end/test_health_check_service_impl.h - - test/cpp/interop/pre_stop_hook_server.h - - test/cpp/interop/xds_interop_server_lib.h - src: - - src/proto/grpc/health/v1/health.proto - - src/proto/grpc/testing/empty.proto - - src/proto/grpc/testing/istio_echo.proto - - src/proto/grpc/testing/messages.proto - - src/proto/grpc/testing/test.proto - - src/proto/grpc/testing/xds/v3/base.proto - - src/proto/grpc/testing/xds/v3/config_dump.proto - - src/proto/grpc/testing/xds/v3/csds.proto - - src/proto/grpc/testing/xds/v3/percent.proto - - src/cpp/server/admin/admin_services.cc - - src/cpp/server/csds/csds.cc - - test/cpp/end2end/test_health_check_service_impl.cc - - test/cpp/interop/pre_stop_hook_server.cc - - test/cpp/interop/pre_stop_hook_server_test.cc - - test/cpp/interop/xds_interop_server_lib.cc - deps: - - gtest - - grpc++_reflection - - grpcpp_channelz - - grpc_test_util - - grpc++_test_config - name: prioritized_race_test gtest: true build: test @@ -17584,7 +17553,6 @@ targets: headers: - src/cpp/server/csds/csds.h - test/cpp/end2end/test_health_check_service_impl.h - - test/cpp/interop/pre_stop_hook_server.h - test/cpp/interop/xds_interop_server_lib.h src: - src/proto/grpc/health/v1/health.proto @@ -17598,7 +17566,6 @@ targets: - src/cpp/server/admin/admin_services.cc - src/cpp/server/csds/csds.cc - test/cpp/end2end/test_health_check_service_impl.cc - - test/cpp/interop/pre_stop_hook_server.cc - test/cpp/interop/xds_interop_server.cc - test/cpp/interop/xds_interop_server_lib.cc deps: @@ -17613,7 +17580,6 @@ targets: headers: - src/cpp/server/csds/csds.h - test/cpp/end2end/test_health_check_service_impl.h - - test/cpp/interop/pre_stop_hook_server.h - test/cpp/interop/xds_interop_server_lib.h src: - src/proto/grpc/health/v1/health.proto @@ -17628,7 +17594,6 @@ targets: - src/cpp/server/admin/admin_services.cc - src/cpp/server/csds/csds.cc - test/cpp/end2end/test_health_check_service_impl.cc - - test/cpp/interop/pre_stop_hook_server.cc - test/cpp/interop/xds_interop_server_lib.cc - test/cpp/interop/xds_interop_server_test.cc deps: diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto index 3e26bdb5f56..d948ef6a929 100644 --- a/src/proto/grpc/testing/messages.proto +++ b/src/proto/grpc/testing/messages.proto @@ -219,7 +219,7 @@ message LoadBalancerStatsResponse { message RpcMetadata { // metadata values for each rpc for the keys specified in // LoadBalancerStatsRequest.metadata_keys. - // metadata keys and values are returned exactly as was received + // metadata keys and values are returned exactly as was recieved // from the server. repeated MetadataEntry metadata = 1; } @@ -309,23 +309,3 @@ message TestOrcaReport { map request_cost = 3; map utilization = 4; } - -enum HookRequestCommand { - // Start the HTTP endpoint - START = 0; - // Stop - STOP = 1; - // Return from HTTP GET/POST - RETURN = 2; -} - -message HookRequest { - HookRequestCommand command = 1; - int32 grpc_code_to_return = 2; - string grpc_status_description = 3; - // Server port to listen to - int32 server_port = 4; -} - -message HookResponse { -} diff --git a/src/proto/grpc/testing/test.proto b/src/proto/grpc/testing/test.proto index 23a7707191b..5805a41da99 100644 --- a/src/proto/grpc/testing/test.proto +++ b/src/proto/grpc/testing/test.proto @@ -23,8 +23,6 @@ import "src/proto/grpc/testing/messages.proto"; package grpc.testing; -option java_package = "io.grpc.testing.integration"; - // A simple service to test the various types of RPCs and experiment with // performance with various types of payload. service TestService { @@ -91,17 +89,10 @@ service LoadBalancerStatsService { returns (LoadBalancerAccumulatedStatsResponse) {} } -// Hook service that may be started on request by calling XdsUpdateHealthService -// with HookRequestCommand::START -service HookService { - rpc Hook(grpc.testing.Empty) returns (grpc.testing.Empty); -} - // A service to remotely control health status of an xDS test server. service XdsUpdateHealthService { rpc SetServing(grpc.testing.Empty) returns (grpc.testing.Empty); rpc SetNotServing(grpc.testing.Empty) returns (grpc.testing.Empty); - rpc SendHookRequest(HookRequest) returns (HookResponse); } // A service to dynamically update the configuration of an xDS test client. diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index 6877f6a5b09..019686b2b64 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -47,7 +47,7 @@ def test_runner_log(msg): sys.stderr.write('\n%s: %s\n' % (__file__, msg)) def python_args(arg_list): - if platform.system() == 'Windows': + if platform.system() == 'Windows' and arg_list[0].endswith('.py'): return [sys.executable] + arg_list return arg_list diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index a3bc063b1a4..c1f31ad2a6b 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -287,13 +287,9 @@ grpc_cc_library( name = "xds_interop_server_lib", testonly = True, srcs = [ - "pre_stop_hook_server.cc", "xds_interop_server_lib.cc", ], - hdrs = [ - "pre_stop_hook_server.h", - "xds_interop_server_lib.h", - ], + hdrs = ["xds_interop_server_lib.h"], deps = [ "//:grpc++", "//:grpc++_reflection", @@ -323,21 +319,6 @@ grpc_cc_binary( ], ) -grpc_cc_test( - name = "pre_stop_hook_server_test", - srcs = [ - "pre_stop_hook_server_test.cc", - ], - external_deps = ["gtest"], - deps = [ - ":xds_interop_server_lib", - "//:grpc++", - "//src/proto/grpc/testing:istio_echo_proto", - "//test/core/util:grpc_test_util", - "//test/cpp/util:test_config", - ], -) - grpc_cc_test( name = "xds_interop_server_test", srcs = [ diff --git a/test/cpp/interop/pre_stop_hook_server.cc b/test/cpp/interop/pre_stop_hook_server.cc deleted file mode 100644 index 6ddaceda5db..00000000000 --- a/test/cpp/interop/pre_stop_hook_server.cc +++ /dev/null @@ -1,198 +0,0 @@ -// -// -// Copyright 2023 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 "test/cpp/interop/pre_stop_hook_server.h" - -#include - -#include "absl/strings/str_format.h" - -#include - -#include "src/proto/grpc/testing/test.grpc.pb.h" - -namespace grpc { -namespace testing { -namespace { - -class HookServiceImpl final : public HookService::CallbackService { - public: - ServerUnaryReactor* Hook(CallbackServerContext* context, - const Empty* /* request */, - Empty* /* reply */) override { - grpc_core::MutexLock lock(&mu_); - auto reactor = context->DefaultReactor(); - if (pending_status_) { - reactor->Finish(std::move(*pending_status_)); - pending_status_ = absl::nullopt; - } else if (done_) { - reactor->Finish(Status(StatusCode::ABORTED, "Shutting down")); - } else { - pending_requests_.push_back(reactor); - } - request_var_.SignalAll(); - return reactor; - } - - void SetReturnStatus(const Status& status) { - grpc_core::MutexLock lock(&mu_); - if (pending_requests_.empty()) { - pending_status_ = status; - } else { - auto reactor = pending_requests_.begin(); - (*reactor)->Finish(status); - pending_requests_.erase(reactor); - } - request_var_.SignalAll(); - } - - bool TestOnlyExpectRequests(size_t expected_requests_count, - const absl::Duration& timeout) { - grpc_core::MutexLock lock(&mu_); - auto deadline = absl::Now() + timeout; - while (pending_requests_.size() < expected_requests_count && - !request_var_.WaitWithDeadline(&mu_, deadline)) { - } - return pending_requests_.size() >= expected_requests_count; - } - - void Stop() { - grpc_core::MutexLock lock(&mu_); - for (auto request : pending_requests_) { - request->Finish(Status(StatusCode::ABORTED, "Shutting down")); - } - pending_requests_.clear(); - } - - private: - grpc_core::Mutex mu_; - grpc_core::CondVar request_var_ ABSL_GUARDED_BY(&mu_); - absl::optional pending_status_ ABSL_GUARDED_BY(&mu_); - std::vector pending_requests_ ABSL_GUARDED_BY(&mu_); - bool done_ ABSL_GUARDED_BY(&mu_) = false; -}; - -enum class State { kNew, kWaiting, kDone, kShuttingDown }; - -std::unique_ptr BuildHookServer(HookServiceImpl* service, int port) { - ServerBuilder builder; - builder.AddListeningPort(absl::StrFormat("0.0.0.0:%d", port), - grpc::InsecureServerCredentials()); - builder.RegisterService(service); - return builder.BuildAndStart(); -} - -} // namespace - -class PreStopHookServer { - public: - explicit PreStopHookServer(int port, const absl::Duration& startup_timeout) - : server_(BuildHookServer(&hook_service_, port)), - server_thread_(PreStopHookServer::ServerThread, this) { - WaitForState(State::kWaiting, startup_timeout); - } - - ~PreStopHookServer() { - hook_service_.Stop(); - SetState(State::kShuttingDown); - server_->Shutdown(); - server_thread_.join(); - } - - State GetState() { - grpc_core::MutexLock lock(&mu_); - return state_; - } - - void SetState(State state) { - grpc_core::MutexLock lock(&mu_); - state_ = state; - condition_.SignalAll(); - } - - void SetReturnStatus(const Status& status) { - hook_service_.SetReturnStatus(status); - } - - bool TestOnlyExpectRequests(size_t expected_requests_count, - absl::Duration timeout) { - return hook_service_.TestOnlyExpectRequests(expected_requests_count, - timeout); - } - - private: - bool WaitForState(State state, const absl::Duration& timeout) { - grpc_core::MutexLock lock(&mu_); - auto deadline = absl::Now() + timeout; - while (state_ != state && !condition_.WaitWithDeadline(&mu_, deadline)) { - } - return state_ == state; - } - - static void ServerThread(PreStopHookServer* server) { - server->SetState(State::kWaiting); - server->server_->Wait(); - server->SetState(State::kDone); - } - - HookServiceImpl hook_service_; - grpc_core::Mutex mu_; - grpc_core::CondVar condition_ ABSL_GUARDED_BY(mu_); - State state_ ABSL_GUARDED_BY(mu_) = State::kNew; - std::unique_ptr server_; - std::thread server_thread_; -}; - -Status PreStopHookServerManager::Start(int port, size_t timeout_s) { - if (server_) { - return Status(StatusCode::ALREADY_EXISTS, - "Pre hook server is already running"); - } - server_ = std::unique_ptr( - new PreStopHookServer(port, absl::Seconds(timeout_s)), - PreStopHookServerDeleter()); - return server_->GetState() == State::kWaiting - ? Status::OK - : Status(StatusCode::DEADLINE_EXCEEDED, "Server have not started"); -} - -Status PreStopHookServerManager::Stop() { - if (!server_) { - return Status(StatusCode::UNAVAILABLE, "Pre hook server is not running"); - } - server_.reset(); - return Status::OK; -} - -void PreStopHookServerManager::Return(StatusCode code, - absl::string_view description) { - server_->SetReturnStatus(Status(code, std::string(description))); -} - -bool PreStopHookServerManager::TestOnlyExpectRequests( - size_t expected_requests_count, const absl::Duration& timeout) { - return server_->TestOnlyExpectRequests(expected_requests_count, timeout); -} - -void PreStopHookServerManager::PreStopHookServerDeleter::operator()( - PreStopHookServer* server) { - delete server; -} - -} // namespace testing -} // namespace grpc diff --git a/test/cpp/interop/pre_stop_hook_server.h b/test/cpp/interop/pre_stop_hook_server.h deleted file mode 100644 index 570e264c555..00000000000 --- a/test/cpp/interop/pre_stop_hook_server.h +++ /dev/null @@ -1,62 +0,0 @@ -// -// -// Copyright 2023 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// - -#ifndef GRPC_TEST_CPP_INTEROP_PRE_STOP_HOOK_SERVER_H -#define GRPC_TEST_CPP_INTEROP_PRE_STOP_HOOK_SERVER_H - -#include - -#include - -#include - -#include "src/core/lib/config/core_configuration.h" - -namespace grpc { -namespace testing { - -// Implementation of the pre-stop hook server. An instance is created to start -// a server and destroyed to stop one. -class PreStopHookServer; - -// Interface for interacting with PreStopHookServer. Provides operations -// required by the protocol, such as start, stop and return from the call. -class PreStopHookServerManager { - public: - Status Start(int port, size_t timeout_s); - Status Stop(); - void Return(StatusCode code, absl::string_view description); - // Suspends the thread until there are pending requests. Returns false - // if the necessary number of requests have not been received before the - // timeout. - bool TestOnlyExpectRequests( - size_t expected_requests_count, - const absl::Duration& timeout = absl::Seconds(15)); - - private: - // Custom deleter so we don't have to include PreStopHookServer in this header - struct PreStopHookServerDeleter { - void operator()(PreStopHookServer* server); - }; - - std::unique_ptr server_; -}; - -} // namespace testing -} // namespace grpc -#endif // GRPC_TEST_CPP_INTEROP_PRE_STOP_HOOK_SERVER_H diff --git a/test/cpp/interop/pre_stop_hook_server_test.cc b/test/cpp/interop/pre_stop_hook_server_test.cc deleted file mode 100644 index a2fcc562603..00000000000 --- a/test/cpp/interop/pre_stop_hook_server_test.cc +++ /dev/null @@ -1,176 +0,0 @@ -// -// Copyright 2023 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 "test/cpp/interop/pre_stop_hook_server.h" - -#include -#include - -#include -#include - -#include "absl/strings/str_format.h" - -#include -#include - -#include "src/proto/grpc/testing/test.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -namespace grpc { -namespace testing { -namespace { - -struct CallInfo { - public: - ClientContext context; - Empty request; - Empty response; - - absl::optional WaitForStatus( - absl::Duration timeout = absl::Seconds(1)) { - grpc_core::MutexLock lock(&mu); - if (!status_.has_value()) { - cv.WaitWithTimeout(&mu, timeout); - } - return status_; - } - - void SetStatus(const Status& status) { - grpc_core::MutexLock lock(&mu); - status_ = status; - cv.SignalAll(); - } - - private: - grpc_core::Mutex mu; - grpc_core::CondVar cv; - absl::optional status_; -}; - -TEST(PreStopHookServer, StartDoRequestStop) { - int port = grpc_pick_unused_port_or_die(); - PreStopHookServerManager server; - Status start_status = server.Start(port, 15); - ASSERT_TRUE(start_status.ok()) << start_status.error_message(); - auto channel = CreateChannel(absl::StrFormat("127.0.0.1:%d", port), - InsecureChannelCredentials()); - ASSERT_TRUE(channel); - CallInfo info; - HookService::Stub stub(std::move(channel)); - stub.async()->Hook(&info.context, &info.request, &info.response, - [&info](Status status) { info.SetStatus(status); }); - ASSERT_EQ(server.TestOnlyExpectRequests(1), 1); - server.Return(StatusCode::INTERNAL, "Just a test"); - auto status = info.WaitForStatus(); - ASSERT_TRUE(status.has_value()); - EXPECT_EQ(status->error_code(), StatusCode::INTERNAL); - EXPECT_EQ(status->error_message(), "Just a test"); -} - -TEST(PreStopHookServer, StartServerWhileAlreadyRunning) { - int port = grpc_pick_unused_port_or_die(); - PreStopHookServerManager server; - Status status = server.Start(port, 15); - ASSERT_TRUE(status.ok()) << status.error_message(); - status = server.Start(port, 15); - ASSERT_EQ(status.error_code(), StatusCode::ALREADY_EXISTS) - << status.error_message(); -} - -TEST(PreStopHookServer, StopServerWhileRequestPending) { - int port = grpc_pick_unused_port_or_die(); - PreStopHookServerManager server; - Status start_status = server.Start(port, 15); - ASSERT_TRUE(start_status.ok()) << start_status.error_message(); - auto channel = CreateChannel(absl::StrFormat("127.0.0.1:%d", port), - InsecureChannelCredentials()); - ASSERT_TRUE(channel); - CallInfo info; - HookService::Stub stub(std::move(channel)); - stub.async()->Hook(&info.context, &info.request, &info.response, - [&info](Status status) { info.SetStatus(status); }); - ASSERT_EQ(server.TestOnlyExpectRequests(1), 1); - ASSERT_TRUE(server.Stop().ok()); - auto status = info.WaitForStatus(); - ASSERT_TRUE(status.has_value()); - EXPECT_EQ(status->error_code(), StatusCode::ABORTED); -} - -TEST(PreStopHookServer, RespondToMultiplePendingRequests) { - std::array info; - int port = grpc_pick_unused_port_or_die(); - PreStopHookServerManager server; - Status start_status = server.Start(port, 15); - ASSERT_TRUE(start_status.ok()) << start_status.error_message(); - auto channel = CreateChannel(absl::StrFormat("127.0.0.1:%d", port), - InsecureChannelCredentials()); - ASSERT_TRUE(channel); - HookService::Stub stub(std::move(channel)); - stub.async()->Hook(&info[0].context, &info[0].request, &info[0].response, - [&info](Status status) { info[0].SetStatus(status); }); - ASSERT_EQ(server.TestOnlyExpectRequests(1), 1); - stub.async()->Hook(&info[1].context, &info[1].request, &info[1].response, - [&info](Status status) { info[1].SetStatus(status); }); - server.TestOnlyExpectRequests(2); - server.Return(StatusCode::INTERNAL, "Just a test"); - auto status = info[0].WaitForStatus(); - ASSERT_TRUE(status.has_value()); - EXPECT_EQ(status->error_code(), StatusCode::INTERNAL); - EXPECT_EQ(status->error_message(), "Just a test"); - status = info[1].WaitForStatus(); - EXPECT_FALSE(status.has_value()); -} - -TEST(PreStopHookServer, StopServerThatNotStarted) { - PreStopHookServerManager server; - Status status = server.Stop(); - EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE) - << status.error_message(); -} - -TEST(PreStopHookServer, SetStatusBeforeRequestReceived) { - int port = grpc_pick_unused_port_or_die(); - PreStopHookServerManager server; - Status start_status = server.Start(port, 15); - server.Return(StatusCode::INTERNAL, "Just a test"); - ASSERT_TRUE(start_status.ok()) << start_status.error_message(); - auto channel = CreateChannel(absl::StrFormat("127.0.0.1:%d", port), - InsecureChannelCredentials()); - ASSERT_TRUE(channel); - HookService::Stub stub(std::move(channel)); - CallInfo info; - stub.async()->Hook(&info.context, &info.request, &info.response, - [&info](Status status) { info.SetStatus(status); }); - auto status = info.WaitForStatus(); - ASSERT_TRUE(status.has_value()); - EXPECT_EQ(status->error_code(), StatusCode::INTERNAL); - EXPECT_EQ(status->error_message(), "Just a test"); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(&argc, argv); - grpc_init(); - auto result = RUN_ALL_TESTS(); - grpc_shutdown(); - return result; -} diff --git a/test/cpp/interop/xds_interop_server_lib.cc b/test/cpp/interop/xds_interop_server_lib.cc index 358b74b397a..310a5d44948 100644 --- a/test/cpp/interop/xds_interop_server_lib.cc +++ b/test/cpp/interop/xds_interop_server_lib.cc @@ -41,7 +41,6 @@ #include "src/proto/grpc/testing/messages.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" #include "test/cpp/end2end/test_health_check_service_impl.h" -#include "test/cpp/interop/pre_stop_hook_server.h" namespace grpc { namespace testing { @@ -114,10 +113,8 @@ class TestServiceImpl : public TestService::Service { class XdsUpdateHealthServiceImpl : public XdsUpdateHealthService::Service { public: explicit XdsUpdateHealthServiceImpl( - HealthCheckServiceImpl* health_check_service, - std::unique_ptr pre_stop_hook_server) - : health_check_service_(health_check_service), - pre_stop_hook_server_(std::move(pre_stop_hook_server)) {} + HealthCheckServiceImpl* health_check_service) + : health_check_service_(health_check_service) {} Status SetServing(ServerContext* /* context */, const Empty* /* request */, Empty* /* response */) override { @@ -133,29 +130,8 @@ class XdsUpdateHealthServiceImpl : public XdsUpdateHealthService::Service { return Status::OK; } - Status SendHookRequest(ServerContext* /* context */, - const HookRequest* request, - HookResponse* /* response */) override { - switch (request->command()) { - case HookRequestCommand::START: - return pre_stop_hook_server_->Start(request->server_port(), 30 /* s */); - case HookRequestCommand::STOP: - return pre_stop_hook_server_->Stop(); - case HookRequestCommand::RETURN: - pre_stop_hook_server_->Return( - static_cast(request->grpc_code_to_return()), - request->grpc_status_description()); - return Status::OK; - default: - return Status( - StatusCode::INVALID_ARGUMENT, - absl::StrFormat("Invalid command %d", request->command())); - } - } - private: HealthCheckServiceImpl* const health_check_service_; - std::unique_ptr pre_stop_hook_server_; }; } // namespace @@ -213,8 +189,7 @@ void RunServer(bool secure_mode, const int port, const int maintenance_port, health_check_service.SetStatus( "grpc.testing.XdsUpdateHealthService", grpc::health::v1::HealthCheckResponse::SERVING); - XdsUpdateHealthServiceImpl update_health_service( - &health_check_service, std::make_unique()); + XdsUpdateHealthServiceImpl update_health_service(&health_check_service); grpc::reflection::InitProtoReflectionServerBuilderPlugin(); ServerBuilder builder; diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 13e08d98fba..24d193c7edd 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -54,4 +54,9 @@ grpc_cc_test( ], ) +filegroup( + name = "resolver_test_record_groups", + srcs = ["resolver_test_record_groups.yaml"], +) + generate_resolver_component_tests() diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index a91bc32649b..67c9067690b 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -75,6 +75,7 @@ def generate_resolver_component_tests(): ], external_deps = [ "absl/flags:flag", + "absl/strings", ], deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, @@ -83,6 +84,7 @@ def generate_resolver_component_tests(): "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", "//test/cpp/util:test_config", + "//test/cpp/util/windows:manifest_file", ], data = [ ":resolver_component_tests_runner", @@ -90,7 +92,7 @@ def generate_resolver_component_tests(): "//test/cpp/naming/utils:dns_server", "//test/cpp/naming/utils:dns_resolver", "//test/cpp/naming/utils:tcp_connect", - "resolver_test_record_groups.yaml", # include the transitive dependency so that the dns server py binary can locate this + "//test/cpp/naming:resolver_test_record_groups", # include the transitive dependency so that the dns server py binary can locate this ], args = [ "--test_bin_name=resolver_component_test%s" % unsecure_build_config_suffix, diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index cf648ac1614..f6a32a646c4 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -47,7 +47,7 @@ def test_runner_log(msg): sys.stderr.write('\n%s: %s\n' % (__file__, msg)) def python_args(arg_list): - if platform.system() == 'Windows': + if platform.system() == 'Windows' and arg_list[0].endswith('.py'): return [sys.executable] + arg_list return arg_list diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc index 1415e3ea0bf..549c7cc5961 100644 --- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc +++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc @@ -1,6 +1,4 @@ -// -// -// Copyright 2017 gRPC authors. +// Copyright 2017 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. @@ -13,13 +11,17 @@ // 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 +#ifndef GPR_WINDOWS +#include +#endif // GPR_WINDOWS + +#include #include #include #include @@ -43,6 +45,9 @@ #include "test/core/util/test_config.h" #include "test/cpp/util/subprocess.h" #include "test/cpp/util/test_config.h" +#ifdef GPR_WINDOWS +#include "test/cpp/util/windows/manifest_file.h" +#endif // GPR_WINDOWS ABSL_FLAG( bool, running_under_bazel, false, @@ -68,48 +73,22 @@ namespace grpc { namespace testing { -void InvokeResolverComponentTestsRunner( +int InvokeResolverComponentTestsRunner( std::string test_runner_bin_path, const std::string& test_bin_path, const std::string& dns_server_bin_path, const std::string& records_config_path, const std::string& dns_resolver_bin_path, const std::string& tcp_connect_bin_path) { int dns_server_port = grpc_pick_unused_port_or_die(); - - SubProcess* test_driver = new SubProcess( + auto test_driver = std::make_unique(std::vector( {std::move(test_runner_bin_path), "--test_bin_path=" + test_bin_path, "--dns_server_bin_path=" + dns_server_bin_path, "--records_config_path=" + records_config_path, "--dns_server_port=" + std::to_string(dns_server_port), "--dns_resolver_bin_path=" + dns_resolver_bin_path, "--tcp_connect_bin_path=" + tcp_connect_bin_path, - "--extra_args=" + absl::GetFlag(FLAGS_extra_args)}); - gpr_mu test_driver_mu; - gpr_mu_init(&test_driver_mu); - gpr_cv test_driver_cv; - gpr_cv_init(&test_driver_cv); - int status = test_driver->Join(); - if (WIFEXITED(status)) { - if (WEXITSTATUS(status)) { - grpc_core::Crash(absl::StrFormat( - "Resolver component test test-runner exited with code %d", - WEXITSTATUS(status))); - } - } else if (WIFSIGNALED(status)) { - grpc_core::Crash(absl::StrFormat( - "Resolver component test test-runner ended from signal %d", - WTERMSIG(status))); - } else { - grpc_core::Crash(absl::StrFormat( - "Resolver component test test-runner ended with unknown status %d", - status)); - } - gpr_mu_lock(&test_driver_mu); - gpr_cv_signal(&test_driver_cv); - gpr_mu_unlock(&test_driver_mu); - delete test_driver; - gpr_mu_destroy(&test_driver_mu); - gpr_cv_destroy(&test_driver_cv); + "--extra_args=" + absl::GetFlag(FLAGS_extra_args)})); + return test_driver->Join(); } } // namespace testing @@ -122,12 +101,14 @@ int main(int argc, char** argv) { grpc_init(); GPR_ASSERT(!absl::GetFlag(FLAGS_test_bin_name).empty()); std::string my_bin = argv[0]; + int result = 0; if (absl::GetFlag(FLAGS_running_under_bazel)) { GPR_ASSERT(!absl::GetFlag(FLAGS_grpc_test_directory_relative_to_test_srcdir) .empty()); // Use bazel's TEST_SRCDIR environment variable to locate the "test data" // binaries. auto test_srcdir = grpc_core::GetEnv("TEST_SRCDIR"); +#ifndef GPR_WINDOWS std::string const bin_dir = test_srcdir.value() + absl::GetFlag(FLAGS_grpc_test_directory_relative_to_test_srcdir) + @@ -135,18 +116,43 @@ int main(int argc, char** argv) { // Invoke bazel's executeable links to the .sh and .py scripts (don't use // the .sh and .py suffixes) to make // sure that we're using bazel's test environment. - grpc::testing::InvokeResolverComponentTestsRunner( + result = grpc::testing::InvokeResolverComponentTestsRunner( bin_dir + "/resolver_component_tests_runner", bin_dir + "/" + absl::GetFlag(FLAGS_test_bin_name), bin_dir + "/utils/dns_server", bin_dir + "/resolver_test_record_groups.yaml", bin_dir + "/utils/dns_resolver", bin_dir + "/utils/tcp_connect"); +#else + grpc::testing::ManifestFile manifest_file( + grpc::testing::NormalizeFilePath(test_srcdir.value()) + "\\MANIFEST"); + grpc::testing::InvokeResolverComponentTestsRunner( + grpc::testing::NormalizeFilePath( + manifest_file.Get("com_github_grpc_grpc/test/cpp/naming/" + "resolver_component_tests_runner.exe")), + grpc::testing::NormalizeFilePath( + manifest_file.Get("com_github_grpc_grpc/test/cpp/naming/" + + absl::GetFlag(FLAGS_test_bin_name) + ".exe")), + grpc::testing::NormalizeFilePath(manifest_file.Get( + "com_github_grpc_grpc/test/cpp/naming/utils/dns_server.exe")), + grpc::testing::NormalizeFilePath( + manifest_file.Get("com_github_grpc_grpc/test/cpp/naming/" + "resolver_test_record_groups.yaml")), + grpc::testing::NormalizeFilePath(manifest_file.Get( + "com_github_grpc_grpc/test/cpp/naming/utils/dns_resolver.exe")), + grpc::testing::NormalizeFilePath(manifest_file.Get( + "com_github_grpc_grpc/test/cpp/naming/utils/tcp_connect.exe"))); +#endif // GPR_WINDOWS } else { +#ifdef GPR_WINDOWS + grpc_core::Crash( + "Resolver component tests runner invoker does not support running " + "without Bazel on Windows for now."); +#endif // GPR_WINDOWS // Get the current binary's directory relative to repo root to invoke the // correct build config (asan/tsan/dbg, etc.). std::string const bin_dir = my_bin.substr(0, my_bin.rfind('/')); // Invoke the .sh and .py scripts directly where they are in source code. - grpc::testing::InvokeResolverComponentTestsRunner( + result = grpc::testing::InvokeResolverComponentTestsRunner( "test/cpp/naming/resolver_component_tests_runner.py", bin_dir + "/" + absl::GetFlag(FLAGS_test_bin_name), "test/cpp/naming/utils/dns_server.py", @@ -155,5 +161,5 @@ int main(int argc, char** argv) { "test/cpp/naming/utils/tcp_connect.py"); } grpc_shutdown(); - return 0; + return result; } diff --git a/test/cpp/util/windows/BUILD b/test/cpp/util/windows/BUILD new file mode 100644 index 00000000000..ffd2352efd4 --- /dev/null +++ b/test/cpp/util/windows/BUILD @@ -0,0 +1,39 @@ +# Copyright 2023 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("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_package") + +licenses(["notice"]) + +grpc_package( + name = "test/cpp/util/windows", + visibility = "tests", +) + +grpc_cc_library( + name = "manifest_file", + testonly = True, + srcs = [ + "manifest_file.cc", + ], + hdrs = [ + "manifest_file.h", + ], + external_deps = [ + "absl/strings", + ], + deps = [ + "//:gpr", + ], +) diff --git a/test/cpp/util/windows/manifest_file.cc b/test/cpp/util/windows/manifest_file.cc new file mode 100644 index 00000000000..a1d4e77553a --- /dev/null +++ b/test/cpp/util/windows/manifest_file.cc @@ -0,0 +1,71 @@ +// Copyright 2023 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. + +#include + +#include "test/cpp/util/windows/manifest_file.h" + +#ifdef GPR_WINDOWS + +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/str_split.h" + +#include + +#include "src/core/lib/gprpp/crash.h" + +namespace grpc { +namespace testing { + +std::string NormalizeFilePath(const std::string& filepath) { + return absl::StrReplaceAll(filepath, {{"/", "\\"}}); +} + +ManifestFile::ManifestFile(const std::string& filepath) + : filestream_(filepath, std::ios::in | std::ios::binary) { + if (!filestream_.is_open()) { + grpc_core::Crash(absl::StrFormat("Failed to open %s", filepath)); + } +} + +std::string ManifestFile::Get(const std::string& key) { + auto iter = cache_.find(key); + if (iter != cache_.end()) { + return iter->second; + } + do { + std::string line; + std::getline(filestream_, line); + if (!line.empty()) { + std::vector kv = absl::StrSplit(line, " "); + GPR_ASSERT(kv.size() == 2); + cache_.emplace(kv[0], kv[1]); + if (kv[0] == key) { + return kv[1]; + } + } + } while (!filestream_.eof() && !filestream_.fail()); + grpc_core::Crash( + absl::StrFormat("Failed to find key: %s in MANIFEST file", key)); +} + +} // namespace testing +} // namespace grpc + +#endif // GPR_WINDOWS diff --git a/test/cpp/util/windows/manifest_file.h b/test/cpp/util/windows/manifest_file.h new file mode 100644 index 00000000000..cca75e2734b --- /dev/null +++ b/test/cpp/util/windows/manifest_file.h @@ -0,0 +1,57 @@ +// Copyright 2023 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. + +#ifndef GRPC_TEST_CPP_UTIL_WINDOWS_MANIFEST_FILE_H +#define GRPC_TEST_CPP_UTIL_WINDOWS_MANIFEST_FILE_H + +#include + +#ifdef GPR_WINDOWS + +#include +#include +#include + +namespace grpc { +namespace testing { + +std::string NormalizeFilePath(const std::string& filepath); + +// This class is used for handling Runfiles for a Bazel target on Windows (e.g. +// the output of targets specified in the data attribute of the target). On +// Linux/macOS, Bazel creates a runfiles tree which contains symlinks to the +// actual runfiles. But on Windows, it only creates a MANIFEST file which +// contains a list of . +// Thus one initializes a ManifestFile object with the filepath to a MANIFEST +// file and uses it as a key-value datastore by querying the absolute symlink +// target path with the imaginative symlink relative path. See +// https://github.com/bazelbuild/bazel/issues/4261#issuecomment-350723457 for +// more details. +class ManifestFile { + public: + explicit ManifestFile(const std::string& filepath); + + std::string Get(const std::string& key); + + private: + std::fstream filestream_; + std::unordered_map cache_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GPR_WINDOWS + +#endif // GRPC_TEST_CPP_UTIL_WINDOWS_MANIFEST_FILE_H diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 05be005caf8..f25c9de92a5 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -6639,30 +6639,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "pre_stop_hook_server_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false,