From 641dbfd4c24be9262b1b49a798e7f8116819d820 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 7 May 2024 14:36:28 -0700 Subject: [PATCH 01/33] [build] Add an assertion for no leaks, use it for event engine shutdown (#36520) Add a test utility to assert there are no memory leaks at an arbitrary point in code (when running under ASAN). Use that utility to help diagnose why event engine fails to shut down. .. also moves some preprocessor junk around in build.cc to make that file a little easier to parse Closes #36520 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36520 from ctiller:leaky-boat 540bfca8c6ead54436ea215bd0afec454329f610 PiperOrigin-RevId: 631552535 --- .../event_engine/event_engine_test_utils.cc | 4 ++ test/core/test_util/build.cc | 70 ++++++++++++------- test/core/test_util/build.h | 3 + 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/test/core/event_engine/event_engine_test_utils.cc b/test/core/event_engine/event_engine_test_utils.cc index cc036ad5d3b..32ab6ac5276 100644 --- a/test/core/event_engine/event_engine_test_utils.cc +++ b/test/core/event_engine/event_engine_test_utils.cc @@ -41,6 +41,7 @@ #include "src/core/lib/gprpp/notification.h" #include "src/core/lib/gprpp/time.h" #include "src/core/lib/resource_quota/memory_quota.h" +#include "test/core/test_util/build.h" // IWYU pragma: no_include @@ -77,7 +78,10 @@ std::string GetNextSendMessage() { } void WaitForSingleOwner(std::shared_ptr engine) { + int n = 0; while (engine.use_count() > 1) { + ++n; + if (n % 100 == 0) AsanAssertNoLeaks(); GRPC_LOG_EVERY_N_SEC(2, GPR_INFO, "engine.use_count() = %ld", engine.use_count()); absl::SleepFor(absl::Milliseconds(100)); diff --git a/test/core/test_util/build.cc b/test/core/test_util/build.cc index 04d39e9574d..36510696681 100644 --- a/test/core/test_util/build.cc +++ b/test/core/test_util/build.cc @@ -12,62 +12,78 @@ // See the License for the specific language governing permissions and // limitations under the License. -bool BuiltUnderValgrind() { -#ifdef RUNNING_ON_VALGRIND - return true; -#else - return false; -#endif -} - -bool BuiltUnderTsan() { +// Define GRPC_BUILD_HAS_ASAN as 1 or 0 depending on if we're building under +// ASAN. #if defined(__has_feature) -#if __has_feature(thread_sanitizer) - return true; +#if __has_feature(address_sanitizer) +#define GRPC_BUILD_HAS_ASAN 1 #else - return false; +#define GRPC_BUILD_HAS_ASAN 0 #endif #else -#ifdef THREAD_SANITIZER - return true; +#ifdef ADDRESS_SANITIZER +#define GRPC_BUILD_HAS_ASAN 1 #else - return false; +#define GRPC_BUILD_HAS_ASAN 0 #endif #endif -} -bool BuiltUnderAsan() { +// Define GRPC_BUILD_HAS_TSAN as 1 or 0 depending on if we're building under +// TSAN. #if defined(__has_feature) -#if __has_feature(address_sanitizer) - return true; +#if __has_feature(thread_sanitizer) +#define GRPC_BUILD_HAS_TSAN 1 #else - return false; +#define GRPC_BUILD_HAS_TSAN 0 #endif #else -#ifdef ADDRESS_SANITIZER - return true; +#ifdef THREAD_SANITIZER +#define GRPC_BUILD_HAS_TSAN 1 #else - return false; +#define GRPC_BUILD_HAS_TSAN 0 #endif #endif -} -bool BuiltUnderMsan() { +// Define GRPC_BUILD_HAS_MSAN as 1 or 0 depending on if we're building under +// MSAN. #if defined(__has_feature) #if __has_feature(memory_sanitizer) - return true; +#define GRPC_BUILD_HAS_MSAN 1 #else - return false; +#define GRPC_BUILD_HAS_MSAN 0 #endif #else #ifdef MEMORY_SANITIZER +#define GRPC_BUILD_HAS_MSAN 1 +#else +#define GRPC_BUILD_HAS_MSAN 0 +#endif +#endif + +#if GRPC_BUILD_HAS_ASAN +#include +#endif + +bool BuiltUnderValgrind() { +#ifdef RUNNING_ON_VALGRIND return true; #else return false; #endif +} + +bool BuiltUnderTsan() { return GRPC_BUILD_HAS_TSAN != 0; } + +bool BuiltUnderAsan() { return GRPC_BUILD_HAS_ASAN != 0; } + +void AsanAssertNoLeaks() { +#if GRPC_BUILD_HAS_ASAN + __lsan_do_leak_check(); #endif } +bool BuiltUnderMsan() { return GRPC_BUILD_HAS_MSAN != 0; } + bool BuiltUnderUbsan() { #ifdef GRPC_UBSAN return true; diff --git a/test/core/test_util/build.h b/test/core/test_util/build.h index 20bc21954ff..8574dfe8d3c 100644 --- a/test/core/test_util/build.h +++ b/test/core/test_util/build.h @@ -30,4 +30,7 @@ bool BuiltUnderMsan(); // Returns whether this is built under UndefinedBehaviorSanitizer bool BuiltUnderUbsan(); +// Force a leak check if built under ASAN. If there are leaks, crash. +void AsanAssertNoLeaks(); + #endif // GRPC_TEST_CORE_TEST_UTIL_BUILD_H From 52f7a6f38d9a52e371066119e997428d76494ac4 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Wed, 8 May 2024 10:38:32 -0700 Subject: [PATCH 02/33] [Interop] Rebuild dart image (#36556) The last time it was rebuilt, the base image (dart:stable) seems not to have been updated. grpc-dart is now requiring newer dart version and is currently failing: https://github.com/grpc/grpc-dart/issues/705 Closes #36556 PiperOrigin-RevId: 631850210 --- tools/bazelify_tests/dockerimage_current_versions.bzl | 2 +- tools/dockerfile/interoptest/grpc_interop_dart.current_version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/bazelify_tests/dockerimage_current_versions.bzl b/tools/bazelify_tests/dockerimage_current_versions.bzl index 423bc0f0237..319c82203b8 100644 --- a/tools/bazelify_tests/dockerimage_current_versions.bzl +++ b/tools/bazelify_tests/dockerimage_current_versions.bzl @@ -72,7 +72,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = { "tools/dockerfile/grpc_artifact_python_musllinux_1_1_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_artifact_python_musllinux_1_1_x86@sha256:c288f83435186ee675d004ee52c93195a51201bf2b5fe92581584d977a2499a3", "tools/dockerfile/interoptest/grpc_interop_aspnetcore.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_aspnetcore@sha256:8e2e732e78724a8382c340dca72e7653c5f82c251a3110fa2874cc00ba538878", "tools/dockerfile/interoptest/grpc_interop_cxx.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_cxx@sha256:e5a474d33773d52ec6a8abbe2d61ee0c2a9c2b5f48793a5ea3b82c4445becf3f", - "tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:2051ef1cf81c463a65853f6058135f48e52a7572cc2bad57182256b77ef61021", + "tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:c44c44706e28c328489ab9cbbf1f2940855c4c341639fbda76b2fc1d561e3383", "tools/dockerfile/interoptest/grpc_interop_go.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go@sha256:889e7ff34399a5e16af87940d1eaa239e56da307f7faca3f8f1d28379c2e3df3", "tools/dockerfile/interoptest/grpc_interop_go1.11.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.11@sha256:f2fe3a0a581c687ee4217bf58fd42b18bb1f63d3d006f1b67379ff553b0e23c6", "tools/dockerfile/interoptest/grpc_interop_go1.16.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.16@sha256:3767f47c9d06584c6c07b7ab536e13f3e87550330e6c2652ad288d3a72b0de23", diff --git a/tools/dockerfile/interoptest/grpc_interop_dart.current_version b/tools/dockerfile/interoptest/grpc_interop_dart.current_version index 2f4f0413adf..061c17c4e1f 100644 --- a/tools/dockerfile/interoptest/grpc_interop_dart.current_version +++ b/tools/dockerfile/interoptest/grpc_interop_dart.current_version @@ -1 +1 @@ -us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:2051ef1cf81c463a65853f6058135f48e52a7572cc2bad57182256b77ef61021 \ No newline at end of file +us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:c44c44706e28c328489ab9cbbf1f2940855c4c341639fbda76b2fc1d561e3383 \ No newline at end of file From 8ad65ab1ca877099fdbf6ffab8b0341c63b0b775 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2024 11:08:30 -0700 Subject: [PATCH 03/33] [http2] Fix http2_stats test's usage of GlobalPluginStatsRegistry (#36561) This should fix errors of the form - https://source.cloud.google.com/results/invocations/84e6c8cd-78df-45a3-8898-d703a2d38ac5/targets/%2F%2Ftest%2Fcore%2Fend2end:http2_stats_test@poller%3Dpoll/log ``` *** SIGSEGV received at time=1715064982 on cpu 0 *** PC: @ 0xffffaf404250 (unknown) absl::lts_20240116::Mutex::Lock() @ 0xffffb406e818 224 absl::lts_20240116::AbslFailureSignalHandler() @ 0xffffb45297b0 4768 (unknown) @ 0xffffb0266888 32 grpc_core::DelegatingClientCallTracer::DelegatingClientCallAttemptTracer::RecordEnd() @ 0xffffb14de408 64 grpc_core::ClientChannelFilter::FilterBasedLoadBalancedCall::Orphan() @ 0xffffb14fd2b0 48 grpc_core::RetryFilter::LegacyCallData::~LegacyCallData() @ 0xffffb14fc8e4 32 grpc_core::RetryFilter::LegacyCallData::Destroy() @ 0xffffb0ebc5bc 32 grpc_call_stack_destroy() @ 0xffffb14f4e34 48 grpc_core::DynamicFilters::Call::Destroy() @ 0xffffaff752b0 48 grpc_core::ExecCtx::Flush() @ 0xffffb44a6fb0 64 grpc_core::ExecCtx::~ExecCtx() @ 0xffffb14f2a90 160 absl::lts_20240116::internal_any_invocable::LocalInvoker<>() @ 0xffffb072c2fc 48 grpc_event_engine::experimental::SelfDeletingClosure::Run() @ 0xffffb072bd78 32 grpc_event_engine::experimental::WorkStealingThreadPool::ThreadState::Step() @ 0xffffb072ba7c 112 grpc_event_engine::experimental::WorkStealingThreadPool::ThreadState::ThreadBody() @ 0xffffb072c33c 48 grpc_event_engine::experimental::WorkStealingThreadPool::WorkStealingThreadPoolImpl::StartThread()::$_0::__invoke() @ 0xffffafb4bdc0 80 grpc_core::(anonymous namespace)::ThreadInternalsPosix::ThreadInternalsPosix()::{lambda()#1}::__invoke() @ 0xffffaef95648 80 start_thread ``` I wasn't able to reproduce this but the fix seems correct. Internal ref: b/339452200 Closes #36561 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36561 from yashykt:FixHttp2StatsTest 88f29629b1721eb9998f6c4ab6755b68bb31a8d0 PiperOrigin-RevId: 631860860 --- test/core/end2end/tests/http2_stats.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/core/end2end/tests/http2_stats.cc b/test/core/end2end/tests/http2_stats.cc index f0421d67dd0..a2931c98ea6 100644 --- a/test/core/end2end/tests/http2_stats.cc +++ b/test/core/end2end/tests/http2_stats.cc @@ -199,6 +199,7 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) { g_mu = new Mutex(); g_client_call_ended_notify = new CoreEnd2endTest::TestNotification(this); g_server_call_ended_notify = new CoreEnd2endTest::TestNotification(this); + GlobalStatsPluginRegistryTestPeer::ResetGlobalStatsPluginRegistry(); GlobalStatsPluginRegistry::RegisterStatsPlugin( std::make_shared()); auto send_from_client = RandomSlice(10); @@ -265,8 +266,6 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) { EXPECT_GE(server_transport_stats.incoming.framing_bytes, 32); EXPECT_LE(server_transport_stats.incoming.framing_bytes, 58); - delete ServerCallTracerFactory::Get(ChannelArgs()); - ServerCallTracerFactory::RegisterGlobal(nullptr); delete g_client_call_ended_notify; g_client_call_ended_notify = nullptr; delete g_server_call_ended_notify; From abda964f52434e67afa092c6f044aedd6b49d699 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Wed, 8 May 2024 11:38:11 -0700 Subject: [PATCH 04/33] [Interop] Rebuild dart image (#36562) This is the same change as in #36556, but the change was committed without the second commit that existed in the PR (due to a very wide wait-for-CI-before-syncing race). The sha here is what's currently in testing-images-public. I don't know where it came from but it has the proper update. Closes #36562 PiperOrigin-RevId: 631871629 --- tools/bazelify_tests/dockerimage_current_versions.bzl | 2 +- tools/dockerfile/interoptest/grpc_interop_dart.current_version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/bazelify_tests/dockerimage_current_versions.bzl b/tools/bazelify_tests/dockerimage_current_versions.bzl index 319c82203b8..016e3ae75ed 100644 --- a/tools/bazelify_tests/dockerimage_current_versions.bzl +++ b/tools/bazelify_tests/dockerimage_current_versions.bzl @@ -72,7 +72,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = { "tools/dockerfile/grpc_artifact_python_musllinux_1_1_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_artifact_python_musllinux_1_1_x86@sha256:c288f83435186ee675d004ee52c93195a51201bf2b5fe92581584d977a2499a3", "tools/dockerfile/interoptest/grpc_interop_aspnetcore.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_aspnetcore@sha256:8e2e732e78724a8382c340dca72e7653c5f82c251a3110fa2874cc00ba538878", "tools/dockerfile/interoptest/grpc_interop_cxx.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_cxx@sha256:e5a474d33773d52ec6a8abbe2d61ee0c2a9c2b5f48793a5ea3b82c4445becf3f", - "tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:c44c44706e28c328489ab9cbbf1f2940855c4c341639fbda76b2fc1d561e3383", + "tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:4915a280788126dad029858eb384dbbef2dc18cadccb434df6450dfd7a4929f2", "tools/dockerfile/interoptest/grpc_interop_go.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go@sha256:889e7ff34399a5e16af87940d1eaa239e56da307f7faca3f8f1d28379c2e3df3", "tools/dockerfile/interoptest/grpc_interop_go1.11.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.11@sha256:f2fe3a0a581c687ee4217bf58fd42b18bb1f63d3d006f1b67379ff553b0e23c6", "tools/dockerfile/interoptest/grpc_interop_go1.16.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.16@sha256:3767f47c9d06584c6c07b7ab536e13f3e87550330e6c2652ad288d3a72b0de23", diff --git a/tools/dockerfile/interoptest/grpc_interop_dart.current_version b/tools/dockerfile/interoptest/grpc_interop_dart.current_version index 061c17c4e1f..1a055c61de7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_dart.current_version +++ b/tools/dockerfile/interoptest/grpc_interop_dart.current_version @@ -1 +1 @@ -us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:c44c44706e28c328489ab9cbbf1f2940855c4c341639fbda76b2fc1d561e3383 \ No newline at end of file +us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:4915a280788126dad029858eb384dbbef2dc18cadccb434df6450dfd7a4929f2 \ No newline at end of file From 28f2315c9f0310f34bdd6c3d557f1c16f6c45b1b Mon Sep 17 00:00:00 2001 From: Eugene Ostroukhov Date: Wed, 8 May 2024 14:01:38 -0700 Subject: [PATCH 05/33] [EventEngine] Rely on RAII for lifeguard (#36555) This makes lifeguard easier to manage and removes one case of hang in fork test. Closes #36555 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36555 from eugeneo:lifeguard-lifetime d6f245cf6909c718ada49df1491ffedf31480b3c PiperOrigin-RevId: 631917491 --- .../thread_pool/work_stealing_thread_pool.cc | 20 +++++++++---------- .../thread_pool/work_stealing_thread_pool.h | 9 +++------ 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc index a923b293a9e..eeaed8abb3c 100644 --- a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +++ b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc @@ -227,18 +227,19 @@ void WorkStealingThreadPool::PostforkChild() { pool_->Postfork(); } WorkStealingThreadPool::WorkStealingThreadPoolImpl::WorkStealingThreadPoolImpl( size_t reserve_threads) - : reserve_threads_(reserve_threads), queue_(this), lifeguard_(this) {} + : reserve_threads_(reserve_threads), queue_(this) {} void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Start() { for (size_t i = 0; i < reserve_threads_; i++) { StartThread(); } - lifeguard_.Start(); + grpc_core::MutexLock lock(&lifeguard_ptr_mu_); + lifeguard_ = std::make_unique(this); } void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Run( EventEngine::Closure* closure) { - DCHECK(quiesced_.load(std::memory_order_relaxed) == false); + CHECK(!IsQuiesced()); if (g_local_queue != nullptr && g_local_queue->owner() == this) { g_local_queue->Add(closure); } else { @@ -283,7 +284,8 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Quiesce() { } CHECK(queue_.Empty()); quiesced_.store(true, std::memory_order_relaxed); - lifeguard_.BlockUntilShutdownAndReset(); + grpc_core::MutexLock lock(&lifeguard_ptr_mu_); + lifeguard_.reset(); } bool WorkStealingThreadPool::WorkStealingThreadPoolImpl::SetThrottled( @@ -325,7 +327,8 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::PrepareFork() { if (!threads_were_shut_down.ok() && g_log_verbose_failures) { DumpStacksAndCrash(); } - lifeguard_.BlockUntilShutdownAndReset(); + grpc_core::MutexLock lock(&lifeguard_ptr_mu_); + lifeguard_.reset(); } void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Postfork() { @@ -374,9 +377,7 @@ WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::Lifeguard( .set_max_backoff(kLifeguardMaxSleepBetweenChecks) .set_multiplier(1.3)), lifeguard_should_shut_down_(std::make_unique()), - lifeguard_is_shut_down_(std::make_unique()) {} - -void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::Start() { + lifeguard_is_shut_down_(std::make_unique()) { // lifeguard_running_ is set early to avoid a quiesce race while the // lifeguard is still starting up. lifeguard_running_.store(true); @@ -411,8 +412,7 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard:: lifeguard_is_shut_down_->Notify(); } -void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard:: - BlockUntilShutdownAndReset() { +WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::~Lifeguard() { lifeguard_should_shut_down_->Notify(); while (lifeguard_running_.load(std::memory_order_relaxed)) { GRPC_LOG_EVERY_N_SEC_DELAYED(kBlockingQuiesceLogRateSeconds, GPR_DEBUG, diff --git a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h index 3dcc55aab6c..7543db92900 100644 --- a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +++ b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h @@ -155,11 +155,7 @@ class WorkStealingThreadPool final : public ThreadPool { class Lifeguard { public: explicit Lifeguard(WorkStealingThreadPoolImpl* pool); - // Start the lifeguard thread. - void Start(); - // Block until the lifeguard thread is shut down. - // Afterwards, reset the lifeguard state so it can start again cleanly. - void BlockUntilShutdownAndReset(); + ~Lifeguard(); private: // The main body of the lifeguard thread. @@ -194,7 +190,8 @@ class WorkStealingThreadPool final : public ThreadPool { // at a time. std::atomic throttled_{false}; WorkSignal work_signal_; - Lifeguard lifeguard_; + grpc_core::Mutex lifeguard_ptr_mu_; + std::unique_ptr lifeguard_ ABSL_GUARDED_BY(lifeguard_ptr_mu_); // Set of threads for verbose failure debugging grpc_core::Mutex thd_set_mu_; absl::flat_hash_set thds_ ABSL_GUARDED_BY(thd_set_mu_); From 22e9ce46e0e0703e7fe25ba9613ef442a76fafcf Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2024 14:01:49 -0700 Subject: [PATCH 06/33] [CSM] Minor test modifications (#36564) Closes #36564 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36564 from yashykt:MetadataExchangeTestFixes 095bdcdd48d29c82edb1809c0107fd43aac81ea5 PiperOrigin-RevId: 631917562 --- test/cpp/ext/csm/metadata_exchange_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/cpp/ext/csm/metadata_exchange_test.cc b/test/cpp/ext/csm/metadata_exchange_test.cc index 0a37a1cbc1d..aeaad05117d 100644 --- a/test/cpp/ext/csm/metadata_exchange_test.cc +++ b/test/cpp/ext/csm/metadata_exchange_test.cc @@ -397,6 +397,9 @@ TEST_P(MetadataExchangeTest, ClientDoesNotSendMetadata) { EXPECT_EQ(absl::get(attributes.at("csm.mesh_id")), "mesh-id"); EXPECT_EQ(absl::get(attributes.at("csm.remote_workload_type")), "unknown"); + EXPECT_EQ(absl::get( + attributes.at("csm.remote_workload_canonical_service")), + "unknown"); } TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) { @@ -424,6 +427,8 @@ TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) { "mynamespace"); } +// Test that metadata exchange works and corresponding service mesh labels are +// received and recorded even if the server sends a trailers-only response. TEST_P(MetadataExchangeTest, Retries) { Init(std::move( Options() From 740b58a9ac8e3b7381956f8941a45cec6bf416df Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Wed, 8 May 2024 15:38:40 -0700 Subject: [PATCH 07/33] Reintroduced GCC 7 test (#36565) GCC 7 was disabled due to its gcc internal error while building protobuf C++. But we still need to support gcc7 and there appear to be issues causing gcc 7 to not build grpc so let's reintroduce gcc 7 test. Closes #36565 PiperOrigin-RevId: 631947203 --- .../test/cxx_gcc_7_x64/Dockerfile.template | 28 +++++++ .../dockerimage_current_versions.bzl | 1 + .../bazelify_tests/test/portability_tests.bzl | 2 +- .../test/cxx_gcc_7_x64.current_version | 1 + .../dockerfile/test/cxx_gcc_7_x64/Dockerfile | 79 +++++++++++++++++++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template create mode 100644 tools/dockerfile/test/cxx_gcc_7_x64.current_version create mode 100644 tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile diff --git a/templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template new file mode 100644 index 00000000000..f3a5a484e2e --- /dev/null +++ b/templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template @@ -0,0 +1,28 @@ +%YAML 1.2 +--- | + # Copyright 2021 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 gcc:7 + + RUN apt-get update && apt-get install -y curl git time wget zip && apt-get clean + <%include file="../../git_avoid_dubious_ownership_error.include"/> + <%include file="../../run_tests_python_deps.include"/> + <%include file="../../cxx_test_deps.include"/> + <%include file="../../cmake.include"/> + <%include file="../../ccache_old.include"/> + <%include file="../../run_tests_addons.include"/> + + # Define the default command. + CMD ["bash"] diff --git a/tools/bazelify_tests/dockerimage_current_versions.bzl b/tools/bazelify_tests/dockerimage_current_versions.bzl index 016e3ae75ed..091fcb09c77 100644 --- a/tools/bazelify_tests/dockerimage_current_versions.bzl +++ b/tools/bazelify_tests/dockerimage_current_versions.bzl @@ -102,6 +102,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = { "tools/dockerfile/test/cxx_debian11_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_debian11_x86@sha256:3f505ad99e52a4b3337fedb413e883bc8e5c1d9c089299c34002b89e01254d3b", "tools/dockerfile/test/cxx_debian12_openssl309_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_debian12_openssl309_x64@sha256:f75bb715c4f9464526f9affb410f7965a0b8894516d7d98cd89a4e165ae065b7", "tools/dockerfile/test/cxx_gcc_12_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_12_x64@sha256:bbdfe66f27b964f9bfd526646b94a19d904fea52bdb244f32fd4355cc8c4551f", + "tools/dockerfile/test/cxx_gcc_7_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_7_x64@sha256:fb1924844078f48557d6ab57eac1482f80a3cc216406efc3aeaecab671c886d5", "tools/dockerfile/test/cxx_gcc_8_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_8_x64@sha256:989ceb4324a6240940d7185ccb581f8eff656d2c8c36d15fa14e3f57f294c913", "tools/dockerfile/test/php73_zts_debian11_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/php73_zts_debian11_x64@sha256:186a96566a9c11adfb198309431086bdb02421121c262a2bf0166e3e9b21fb37", "tools/dockerfile/test/php7_debian11_arm64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/php7_debian11_arm64@sha256:7ee21f253a2ddd255f4f6779cd19818eec6524e78b0bf0a7765339e4aa7347c3", diff --git a/tools/bazelify_tests/test/portability_tests.bzl b/tools/bazelify_tests/test/portability_tests.bzl index bfcc4fbde23..e3328126cbf 100644 --- a/tools/bazelify_tests/test/portability_tests.bzl +++ b/tools/bazelify_tests/test/portability_tests.bzl @@ -53,7 +53,7 @@ def generate_run_tests_portability_tests(name): # C and C++ under different compilers for language in ["c", "c++"]: compiler_configs = [ - ["gcc_7", "", "tools/dockerfile/test/cxx_gcc_8_x64.current_version"], + ["gcc_7", "", "tools/dockerfile/test/cxx_gcc_7_x64.current_version"], ["gcc_12", "--cmake_configure_extra_args=-DCMAKE_CXX_STANDARD=20", "tools/dockerfile/test/cxx_gcc_12_x64.current_version"], ["gcc10.2_openssl102", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl102_x64.current_version"], ["gcc10.2_openssl111", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl111_x64.current_version"], diff --git a/tools/dockerfile/test/cxx_gcc_7_x64.current_version b/tools/dockerfile/test/cxx_gcc_7_x64.current_version new file mode 100644 index 00000000000..de82ae1b550 --- /dev/null +++ b/tools/dockerfile/test/cxx_gcc_7_x64.current_version @@ -0,0 +1 @@ +us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_7_x64:8bc7b7f679857e741188d07a7db7acecf3a9168f@sha256:fb1924844078f48557d6ab57eac1482f80a3cc216406efc3aeaecab671c886d5 \ No newline at end of file diff --git a/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile b/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile new file mode 100644 index 00000000000..a5f56d45055 --- /dev/null +++ b/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile @@ -0,0 +1,79 @@ +# Copyright 2021 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 gcc:7 + +RUN apt-get update && apt-get install -y curl git time wget zip && apt-get clean +#================= +# Setup git to access working directory across docker boundary. +# This avoids the "fatal: detected dubious ownership in repository XYZ" +# git error. + +RUN git config --global --add safe.directory '*' +RUN git config --global protocol.file.allow always + +#==================== +# run_tests.py python dependencies + +# Basic python dependencies to be able to run tools/run_tests python scripts +# These dependencies are not sufficient to build gRPC Python, gRPC Python +# deps are defined elsewhere (e.g. python_deps.include) +RUN apt-get update && apt-get install -y \ + python3 \ + python3-pip \ + python3-setuptools \ + python3-yaml \ + && apt-get clean + +# use pinned version of pip to avoid sudden breakages +RUN python3 -m pip install --upgrade pip==19.3.1 + +# TODO(jtattermusch): currently six is needed for tools/run_tests scripts +# but since our python2 usage is deprecated, we should get rid of it. +RUN python3 -m pip install six==1.16.0 + +# Google Cloud Platform API libraries +# These are needed for uploading test results to BigQuery (e.g. by tools/run_tests scripts) +RUN python3 -m pip install --upgrade google-auth==1.23.0 google-api-python-client==1.12.8 oauth2client==4.1.0 + + +# Some cxx tests depend on the twisted package +RUN python3 -m pip install twisted + +#================= +# Install cmake +# Note that this step should be only used for distributions that have new enough cmake to satisfy gRPC's cmake version requirement. + +RUN apt-get update && apt-get install -y cmake && apt-get clean + +#================= +# Install ccache (use slighly older release of ccache that works older compilers and cmake) + +# Install ccache from source since ccache 3.x packaged with most linux distributions +# does not support Redis backend for caching. +RUN curl -sSL -o ccache.tar.gz https://github.com/ccache/ccache/releases/download/v4.5.1/ccache-4.5.1.tar.gz \ + && tar -zxf ccache.tar.gz \ + && cd ccache-4.5.1 \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release -DZSTD_FROM_INTERNET=ON -DHIREDIS_FROM_INTERNET=ON .. \ + && make -j4 && make install \ + && cd ../.. \ + && rm -rf ccache-4.5.1 ccache.tar.gz + + +RUN mkdir /var/local/jenkins + + +# Define the default command. +CMD ["bash"] From 527950143af5ab3834e3245d31064265e4559aae Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Wed, 8 May 2024 21:13:17 -0700 Subject: [PATCH 08/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36549) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36549 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36549 from tanvi-jagtap:test_cpp_qps_tjagtap 97642463d221a2c60714254b786868d0cc83db71 PiperOrigin-RevId: 632020595 --- test/cpp/qps/BUILD | 5 ++- test/cpp/qps/driver.cc | 55 +++++++++++++++++---------------- test/cpp/qps/report.cc | 69 ++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 66 deletions(-) diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 53292ea0a74..554f29fea62 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -77,7 +77,10 @@ grpc_cc_library( "driver.h", "report.h", ], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], deps = [ ":histogram", ":parse_json", diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 5c5887c65b5..e8ee2da4539 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -26,10 +26,10 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "google/protobuf/timestamp.pb.h" #include -#include #include #include #include @@ -78,13 +78,13 @@ static deque get_workers(const string& env_name) { } } if (out.empty()) { - gpr_log(GPR_ERROR, - "Environment variable \"%s\" does not contain a list of QPS " - "workers to use. Set it to a comma-separated list of " - "hostname:port pairs, starting with hosts that should act as " - "servers. E.g. export " - "%s=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\"", - env_name.c_str(), env_name.c_str()); + LOG(ERROR) << "Environment variable \"" << env_name + << "\" does not contain a list of QPS " + "workers to use. Set it to a comma-separated list of " + "hostname:port pairs, starting with hosts that should act as " + "servers. E.g. export " + << env_name + << "=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\""; } return out; } @@ -237,7 +237,7 @@ struct ServerData { static void FinishClients(const std::vector& clients, const ClientArgs& client_mark) { - gpr_log(GPR_INFO, "Finishing clients"); + LOG(INFO) << "Finishing clients"; for (size_t i = 0, i_end = clients.size(); i < i_end; i++) { auto client = &clients[i]; if (!client->stream->Write(client_mark)) { @@ -252,13 +252,13 @@ static void FinishClients(const std::vector& clients, static void ReceiveFinalStatusFromClients( const std::vector& clients, Histogram& merged_latencies, std::unordered_map& merged_statuses, ScenarioResult& result) { - gpr_log(GPR_INFO, "Receiving final status from clients"); + LOG(INFO) << "Receiving final status from clients"; ClientStatus client_status; for (size_t i = 0, i_end = clients.size(); i < i_end; i++) { auto client = &clients[i]; // Read the client final status if (client->stream->Read(&client_status)) { - gpr_log(GPR_INFO, "Received final status from client %zu", i); + LOG(INFO) << "Received final status from client " << i; const auto& stats = client_status.stats(); merged_latencies.MergeProto(stats.latencies()); for (int i = 0; i < stats.request_results_size(); i++) { @@ -282,7 +282,7 @@ static void ReceiveFinalStatusFromClients( static void ShutdownClients(const std::vector& clients, ScenarioResult& result) { - gpr_log(GPR_INFO, "Shutdown clients"); + LOG(INFO) << "Shutdown clients"; for (size_t i = 0, i_end = clients.size(); i < i_end; i++) { auto client = &clients[i]; Status s = client->stream->Finish(); @@ -300,7 +300,7 @@ static void ShutdownClients(const std::vector& clients, static void FinishServers(const std::vector& servers, const ServerArgs& server_mark) { - gpr_log(GPR_INFO, "Finishing servers"); + LOG(INFO) << "Finishing servers"; for (size_t i = 0, i_end = servers.size(); i < i_end; i++) { auto server = &servers[i]; if (!server->stream->Write(server_mark)) { @@ -314,13 +314,13 @@ static void FinishServers(const std::vector& servers, static void ReceiveFinalStatusFromServer(const std::vector& servers, ScenarioResult& result) { - gpr_log(GPR_INFO, "Receiving final status from servers"); + LOG(INFO) << "Receiving final status from servers"; ServerStatus server_status; for (size_t i = 0, i_end = servers.size(); i < i_end; i++) { auto server = &servers[i]; // Read the server final status if (server->stream->Read(&server_status)) { - gpr_log(GPR_INFO, "Received final status from server %zu", i); + LOG(INFO) << "Received final status from server " << i; result.add_server_stats()->CopyFrom(server_status.stats()); result.add_server_cores(server_status.cores()); // That final status should be the last message on the server stream @@ -334,7 +334,7 @@ static void ReceiveFinalStatusFromServer(const std::vector& servers, static void ShutdownServers(const std::vector& servers, ScenarioResult& result) { - gpr_log(GPR_INFO, "Shutdown servers"); + LOG(INFO) << "Shutdown servers"; for (size_t i = 0, i_end = servers.size(); i < i_end; i++) { auto server = &servers[i]; Status s = server->stream->Finish(); @@ -430,8 +430,8 @@ std::unique_ptr RunScenario( ChannelArguments channel_args; for (size_t i = 0; i < num_servers; i++) { - gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")", - workers[i].c_str(), i); + LOG(INFO) << "Starting server on " << workers[i] << " (worker #" << i + << ")"; if (!run_inproc) { servers[i].stub = WorkerService::NewStub(grpc::CreateTestChannel( workers[i], @@ -487,8 +487,8 @@ std::unique_ptr RunScenario( size_t channels_allocated = 0; for (size_t i = 0; i < num_clients; i++) { const auto& worker = workers[i + num_servers]; - gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", - worker.c_str(), i + num_servers); + LOG(INFO) << "Starting client on " << worker << " (worker #" + << i + num_servers << ")"; if (!run_inproc) { clients[i].stub = WorkerService::NewStub(grpc::CreateTestChannel( worker, @@ -510,8 +510,7 @@ std::unique_ptr RunScenario( (client_config.client_channels() - channels_allocated) / (num_clients - i); channels_allocated += num_channels; - gpr_log(GPR_DEBUG, "Client %" PRIdPTR " gets %" PRIdPTR " channels", i, - num_channels); + VLOG(2) << "Client " << i << " gets " << num_channels << " channels"; per_client_config.set_client_channels(num_channels); ClientArgs args; @@ -533,7 +532,7 @@ std::unique_ptr RunScenario( // Send an initial mark: clients can use this to know that everything is ready // to start - gpr_log(GPR_INFO, "Initiating"); + LOG(INFO) << "Initiating"; ServerArgs server_mark; server_mark.mutable_mark()->set_reset(true); ClientArgs client_mark; @@ -555,13 +554,13 @@ std::unique_ptr RunScenario( } // Let everything warmup - gpr_log(GPR_INFO, "Warming up"); + LOG(INFO) << "Warming up"; gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); gpr_sleep_until( gpr_time_add(start, gpr_time_from_seconds(warmup_seconds, GPR_TIMESPAN))); // Start a run - gpr_log(GPR_INFO, "Starting"); + LOG(INFO) << "Starting"; auto start_time = time(nullptr); @@ -593,7 +592,7 @@ std::unique_ptr RunScenario( } // Wait some time - gpr_log(GPR_INFO, "Running"); + LOG(INFO) << "Running"; // Use gpr_sleep_until rather than this_thread::sleep_until to support // compilers that don't work with this_thread gpr_sleep_until(gpr_time_add( @@ -669,8 +668,8 @@ bool RunQuit( ctx.set_wait_for_ready(true); Status s = stub->QuitWorker(&ctx, phony, &phony); if (!s.ok()) { - gpr_log(GPR_ERROR, "Worker %zu could not be properly quit because %s", i, - s.error_message().c_str()); + LOG(ERROR) << "Worker " << i << " could not be properly quit because " + << s.error_message(); result = false; } } diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc index 87ae89f0f2e..fa43276cf86 100644 --- a/test/cpp/qps/report.cc +++ b/test/cpp/qps/report.cc @@ -20,7 +20,8 @@ #include -#include +#include "absl/log/log.h" + #include #include "src/core/lib/gprpp/crash.h" @@ -79,58 +80,52 @@ void CompositeReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) { } void GprLogReporter::ReportQPS(const ScenarioResult& result) { - gpr_log(GPR_INFO, "QPS: %.1f", result.summary().qps()); + LOG(INFO) << "QPS: " << result.summary().qps(); if (result.summary().failed_requests_per_second() > 0) { - gpr_log(GPR_INFO, "failed requests/second: %.1f", - result.summary().failed_requests_per_second()); - gpr_log(GPR_INFO, "successful requests/second: %.1f", - result.summary().successful_requests_per_second()); + LOG(INFO) << "failed requests/second: " + << result.summary().failed_requests_per_second(); + LOG(INFO) << "successful requests/second: " + << result.summary().successful_requests_per_second(); } } void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result) { - gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", result.summary().qps(), - result.summary().qps_per_server_core()); + LOG(INFO) << "QPS: " << result.summary().qps() << " (" + << result.summary().qps_per_server_core() << "/server core)"; } void GprLogReporter::ReportLatency(const ScenarioResult& result) { - gpr_log(GPR_INFO, - "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us", - result.summary().latency_50() / 1000, - result.summary().latency_90() / 1000, - result.summary().latency_95() / 1000, - result.summary().latency_99() / 1000, - result.summary().latency_999() / 1000); + LOG(INFO) << "Latencies (50/90/95/99/99.9%-ile): " + << result.summary().latency_50() / 1000 << "/" + << result.summary().latency_90() / 1000 << "/" + << result.summary().latency_95() / 1000 << "/" + << result.summary().latency_99() / 1000 << "/" + << result.summary().latency_999() / 1000 << " us"; } void GprLogReporter::ReportTimes(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Server system time: %.2f%%", - result.summary().server_system_time()); - gpr_log(GPR_INFO, "Server user time: %.2f%%", - result.summary().server_user_time()); - gpr_log(GPR_INFO, "Client system time: %.2f%%", - result.summary().client_system_time()); - gpr_log(GPR_INFO, "Client user time: %.2f%%", - result.summary().client_user_time()); + LOG(INFO) << "Server system time: " << result.summary().server_system_time(); + LOG(INFO) << "Server user time: " << result.summary().server_user_time(); + LOG(INFO) << "Client system time: " << result.summary().client_system_time(); + LOG(INFO) << "Client user time: " << result.summary().client_user_time(); } void GprLogReporter::ReportCpuUsage(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Server CPU usage: %.2f%%", - result.summary().server_cpu_usage()); + LOG(INFO) << "Server CPU usage: " << result.summary().server_cpu_usage(); } void GprLogReporter::ReportPollCount(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Client Polls per Request: %.2f", - result.summary().client_polls_per_request()); - gpr_log(GPR_INFO, "Server Polls per Request: %.2f", - result.summary().server_polls_per_request()); + LOG(INFO) << "Client Polls per Request: " + << result.summary().client_polls_per_request(); + LOG(INFO) << "Server Polls per Request: " + << result.summary().server_polls_per_request(); } void GprLogReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Server Queries/CPU-sec: %.2f", - result.summary().server_queries_per_cpu_sec()); - gpr_log(GPR_INFO, "Client Queries/CPU-sec: %.2f", - result.summary().client_queries_per_cpu_sec()); + LOG(INFO) << "Server Queries/CPU-sec: " + << result.summary().server_queries_per_cpu_sec(); + LOG(INFO) << "Client Queries/CPU-sec: " + << result.summary().client_queries_per_cpu_sec(); } void JsonReporter::ReportQPS(const ScenarioResult& result) { @@ -170,14 +165,14 @@ void RpcReporter::ReportQPS(const ScenarioResult& result) { grpc::Status status; Void phony; - gpr_log(GPR_INFO, "RPC reporter sending scenario result to server"); + LOG(INFO) << "RPC reporter sending scenario result to server"; status = stub_->ReportScenario(&context, result, &phony); if (status.ok()) { - gpr_log(GPR_INFO, "RpcReporter report RPC success!"); + LOG(INFO) << "RpcReporter report RPC success!"; } else { - gpr_log(GPR_ERROR, "RpcReporter report RPC: code: %d. message: %s", - status.error_code(), status.error_message().c_str()); + LOG(ERROR) << "RpcReporter report RPC: code: " << status.error_code() + << ". message: " << status.error_message(); } } From e3be06ee38091c4cc2bbdc9af5dbdd9c1e8b2b7b Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Wed, 8 May 2024 21:13:27 -0700 Subject: [PATCH 09/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36548) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36548 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36548 from tanvi-jagtap:test_cpp_e2e_grpclb_clientlb_tjagtap 9f49be3401766a0d1e12be0eaa1695e117939bb7 PiperOrigin-RevId: 632020624 --- test/cpp/end2end/BUILD | 2 + test/cpp/end2end/client_lb_end2end_test.cc | 164 ++++++++++----------- test/cpp/end2end/grpclb_end2end_test.cc | 113 +++++++------- 3 files changed, 140 insertions(+), 139 deletions(-) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 3e01fe662f9..6ada7da27c1 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -529,6 +529,7 @@ grpc_cc_test( srcs = ["client_lb_end2end_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], flaky = True, # TODO(b/151315347) @@ -620,6 +621,7 @@ grpc_cc_test( srcs = ["grpclb_end2end_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], flaky = True, # TODO(b/150567713) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index e7f406f45e9..97cf1f61555 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -26,6 +26,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -424,7 +425,7 @@ class ClientLbEnd2endTest : public ::testing::Test { absl::Seconds(0.1))) {} void Start(const std::string& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); + LOG(INFO) << "starting server on port " << port_; grpc_core::MutexLock lock(&mu_); started_ = true; thread_ = std::make_unique( @@ -433,7 +434,7 @@ class ClientLbEnd2endTest : public ::testing::Test { cond_.Wait(&mu_); } server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); + LOG(INFO) << "server startup complete"; } void Serve(const std::string& server_host) { @@ -498,10 +499,8 @@ class ClientLbEnd2endTest : public ::testing::Test { absl::Duration timeout = absl::Seconds(30)) { if (stop_index == 0) stop_index = servers_.size(); auto deadline = absl::Now() + (timeout * grpc_test_slowdown_factor()); - gpr_log(GPR_INFO, - "========= WAITING FOR BACKENDS [%" PRIuPTR ", %" PRIuPTR - ") ==========", - start_index, stop_index); + LOG(INFO) << "========= WAITING FOR BACKENDS [" << start_index << ", " + << stop_index << ") =========="; while (!SeenAllServers(start_index, stop_index)) { Status status = SendRpc(stub); if (status_check != nullptr) { @@ -636,17 +635,17 @@ TEST_F(ClientLbEnd2endTest, ChannelIdleness) { // The initial channel state should be IDLE. EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); // After sending RPC, channel state should be READY. - gpr_log(GPR_INFO, "*** SENDING RPC, CHANNEL SHOULD CONNECT ***"); + LOG(INFO) << "*** SENDING RPC, CHANNEL SHOULD CONNECT ***"; response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); // After a period time not using the channel, the channel state should switch // to IDLE. - gpr_log(GPR_INFO, "*** WAITING FOR CHANNEL TO GO IDLE ***"); + LOG(INFO) << "*** WAITING FOR CHANNEL TO GO IDLE ***"; gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(1200)); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); // Sending a new RPC should awake the IDLE channel. - gpr_log(GPR_INFO, "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***"); + LOG(INFO) << "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***"; response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); @@ -830,7 +829,7 @@ TEST_F(PickFirstTest, BackOffInitialReconnect) { ASSERT_TRUE(WaitForChannelReady(channel.get())); // Check how long it took. const grpc_core::Duration waited = grpc_core::Timestamp::Now() - t0; - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; // We should have waited at least kInitialBackOffMs. We substract one to // account for test and precision accuracy drift. EXPECT_GE(waited.millis(), @@ -861,7 +860,7 @@ TEST_F(PickFirstTest, BackOffMinReconnect) { const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); const grpc_core::Duration waited = grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; // We should have waited at least kMinReconnectBackOffMs. We substract one to // account for test and precision accuracy drift. EXPECT_GE(waited.millis(), @@ -898,7 +897,7 @@ TEST_F(PickFirstTest, ResetConnectionBackoff) { const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); const grpc_core::Duration waited = grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; // We should have waited less than kInitialBackOffMs. EXPECT_LT(waited.millis(), kInitialBackOffMs * grpc_test_slowdown_factor()); } @@ -919,33 +918,33 @@ TEST_F(ClientLbEnd2endTest, response_generator.SetNextResolution({port}); // Intercept initial connection attempt. auto hold1 = injector.AddHold(port); - gpr_log(GPR_INFO, "=== TRIGGERING INITIAL CONNECTION ATTEMPT"); + LOG(INFO) << "=== TRIGGERING INITIAL CONNECTION ATTEMPT"; EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(/*try_to_connect=*/true)); hold1->Wait(); EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel->GetState(/*try_to_connect=*/false)); // Reset backoff. - gpr_log(GPR_INFO, "=== RESETTING BACKOFF"); + LOG(INFO) << "=== RESETTING BACKOFF"; experimental::ChannelResetConnectionBackoff(channel.get()); // Intercept next attempt. Do this before resuming the first attempt, // just in case the client makes progress faster than this thread. auto hold2 = injector.AddHold(port); // Fail current attempt and wait for next one to start. - gpr_log(GPR_INFO, "=== RESUMING INITIAL ATTEMPT"); + LOG(INFO) << "=== RESUMING INITIAL ATTEMPT"; const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); hold1->Resume(); - gpr_log(GPR_INFO, "=== WAITING FOR SECOND ATTEMPT"); + LOG(INFO) << "=== WAITING FOR SECOND ATTEMPT"; // This WaitForStateChange() call just makes sure we're doing some polling. EXPECT_TRUE(channel->WaitForStateChange(GRPC_CHANNEL_CONNECTING, grpc_timeout_seconds_to_deadline(1))); hold2->Wait(); const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_log(GPR_INFO, "=== RESUMING SECOND ATTEMPT"); + LOG(INFO) << "=== RESUMING SECOND ATTEMPT"; hold2->Resume(); // Elapsed time should be very short, much less than kInitialBackOffMs. const grpc_core::Duration waited = grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; EXPECT_LT(waited.millis(), 1000 * grpc_test_slowdown_factor()); } @@ -958,21 +957,21 @@ TEST_F(PickFirstTest, Updates) { auto stub = BuildStub(channel); // Perform one RPC against the first server. response_generator.SetNextResolution(GetServersPorts(0, 1)); - gpr_log(GPR_INFO, "****** SET [0] *******"); + LOG(INFO) << "****** SET [0] *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(servers_[0]->service_.request_count(), 1); // An empty update will result in the channel going into TRANSIENT_FAILURE. response_generator.SetNextResolution({}); - gpr_log(GPR_INFO, "****** SET none *******"); + LOG(INFO) << "****** SET none *******"; WaitForChannelNotReady(channel.get()); // Next update introduces servers_[1], making the channel recover. response_generator.SetNextResolution(GetServersPorts(1, 2)); - gpr_log(GPR_INFO, "****** SET [1] *******"); + LOG(INFO) << "****** SET [1] *******"; WaitForChannelReady(channel.get()); WaitForServer(DEBUG_LOCATION, stub, 1); // And again for servers_[2] response_generator.SetNextResolution(GetServersPorts(2, 3)); - gpr_log(GPR_INFO, "****** SET [2] *******"); + LOG(INFO) << "****** SET [2] *******"; WaitForServer(DEBUG_LOCATION, stub, 2); // Check LB policy name for the channel. EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); @@ -991,7 +990,7 @@ TEST_F(PickFirstTest, UpdateSuperset) { // Perform one RPC against the first server. ports.emplace_back(servers_[0]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [0] *******"); + LOG(INFO) << "****** SET [0] *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(servers_[0]->service_.request_count(), 1); servers_[0]->service_.ResetCounters(); @@ -1001,7 +1000,7 @@ TEST_F(PickFirstTest, UpdateSuperset) { ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[0]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET superset *******"); + LOG(INFO) << "****** SET superset *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); // We stick to the previously connected server. WaitForServer(DEBUG_LOCATION, stub, 0); @@ -1024,7 +1023,7 @@ TEST_F(PickFirstTest, UpdateToUnconnected) { // Try to send rpcs against a list where the server is available. ports.emplace_back(servers_[0]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [0] *******"); + LOG(INFO) << "****** SET [0] *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); // Send resolution for which all servers are currently unavailable. Eventually @@ -1034,12 +1033,12 @@ TEST_F(PickFirstTest, UpdateToUnconnected) { ports.emplace_back(grpc_pick_unused_port_or_die()); ports.emplace_back(servers_[1]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [unavailable] *******"); + LOG(INFO) << "****** SET [unavailable] *******"; EXPECT_TRUE(WaitForChannelNotReady(channel.get())); // Ensure that the last resolution was installed correctly by verifying that // the channel becomes ready once one of if its endpoints becomes available. - gpr_log(GPR_INFO, "****** StartServer(1) *******"); + LOG(INFO) << "****** StartServer(1) *******"; StartServer(1); EXPECT_TRUE(WaitForChannelReady(channel.get())); } @@ -1135,21 +1134,21 @@ TEST_F(PickFirstTest, ReresolutionNoSelected) { // The initial resolution only contains dead ports. There won't be any // selected subchannel. Re-resolution will return the same result. response_generator.SetNextResolution(dead_ports); - gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******"); + LOG(INFO) << "****** INITIAL RESOLUTION SET *******"; for (size_t i = 0; i < 10; ++i) { CheckRpcSendFailure( DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE, MakeConnectionFailureRegex("failed to connect to all addresses")); } // PF should request re-resolution. - gpr_log(GPR_INFO, "****** WAITING FOR RE-RESOLUTION *******"); + LOG(INFO) << "****** WAITING FOR RE-RESOLUTION *******"; EXPECT_TRUE(response_generator.Get()->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); - gpr_log(GPR_INFO, "****** RE-RESOLUTION SEEN *******"); + LOG(INFO) << "****** RE-RESOLUTION SEEN *******"; // Send a resolver result that contains reachable ports, so that the // pick_first LB policy can recover soon. response_generator.SetNextResolution(alive_ports); - gpr_log(GPR_INFO, "****** RE-RESOLUTION SENT *******"); + LOG(INFO) << "****** RE-RESOLUTION SENT *******"; WaitForServer(DEBUG_LOCATION, stub, 0, [](const Status& status) { EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); EXPECT_THAT(status.error_message(), @@ -1169,12 +1168,12 @@ TEST_F(PickFirstTest, ReconnectWithoutNewResolverResult) { auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); + LOG(INFO) << "****** INITIAL CONNECTION *******"; WaitForServer(DEBUG_LOCATION, stub, 0); - gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); + LOG(INFO) << "****** STOPPING SERVER ******"; servers_[0]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** RESTARTING SERVER ******"); + LOG(INFO) << "****** RESTARTING SERVER ******"; StartServers(1, ports); WaitForServer(DEBUG_LOCATION, stub, 0); } @@ -1188,12 +1187,12 @@ TEST_F(PickFirstTest, ReconnectWithoutNewResolverResultStartsFromTopOfList) { auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); + LOG(INFO) << "****** INITIAL CONNECTION *******"; WaitForServer(DEBUG_LOCATION, stub, 1); - gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); + LOG(INFO) << "****** STOPPING SERVER ******"; servers_[1]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** STARTING BOTH SERVERS ******"); + LOG(INFO) << "****** STARTING BOTH SERVERS ******"; StartServers(2, ports); WaitForServer(DEBUG_LOCATION, stub, 0); } @@ -1202,21 +1201,21 @@ TEST_F(PickFirstTest, FailsEmptyResolverUpdate) { FakeResolverResponseGeneratorWrapper response_generator; auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); - gpr_log(GPR_INFO, "****** SENDING INITIAL RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING INITIAL RESOLVER RESULT *******"; // Send a resolver result with an empty address list and a callback // that triggers a notification. grpc_core::Notification notification; grpc_core::Resolver::Result result; result.addresses.emplace(); result.result_health_callback = [&](absl::Status status) { - gpr_log(GPR_INFO, "****** RESULT HEALTH CALLBACK *******"); + LOG(INFO) << "****** RESULT HEALTH CALLBACK *******"; EXPECT_EQ(absl::StatusCode::kUnavailable, status.code()); EXPECT_EQ("address list must not be empty", status.message()) << status; notification.Notify(); }; response_generator.SetResponse(std::move(result)); // Wait for channel to report TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "****** TELLING CHANNEL TO CONNECT *******"); + LOG(INFO) << "****** TELLING CHANNEL TO CONNECT *******"; auto predicate = [](grpc_connectivity_state state) { return state == GRPC_CHANNEL_TRANSIENT_FAILURE; }; @@ -1225,10 +1224,10 @@ TEST_F(PickFirstTest, FailsEmptyResolverUpdate) { // Callback should run. notification.WaitForNotification(); // Return a valid address. - gpr_log(GPR_INFO, "****** SENDING NEXT RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING NEXT RESOLVER RESULT *******"; StartServers(1); response_generator.SetNextResolution(GetServersPorts()); - gpr_log(GPR_INFO, "****** SENDING WAIT_FOR_READY RPC *******"); + LOG(INFO) << "****** SENDING WAIT_FOR_READY RPC *******"; CheckRpcSendOk(DEBUG_LOCATION, stub, /*wait_for_ready=*/true); } @@ -1239,22 +1238,22 @@ TEST_F(PickFirstTest, CheckStateBeforeStartWatch) { auto channel_1 = BuildChannel("pick_first", response_generator); auto stub_1 = BuildStub(channel_1); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); + LOG(INFO) << "****** RESOLUTION SET FOR CHANNEL 1 *******"; WaitForServer(DEBUG_LOCATION, stub_1, 0); - gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); + LOG(INFO) << "****** CHANNEL 1 CONNECTED *******"; servers_[0]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel_1.get())); // Channel 1 will receive a re-resolution containing the same server. It will // create a new subchannel and hold a ref to it. StartServers(1, ports); - gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); + LOG(INFO) << "****** SERVER RESTARTED *******"; FakeResolverResponseGeneratorWrapper response_generator_2; auto channel_2 = BuildChannel("pick_first", response_generator_2); auto stub_2 = BuildStub(channel_2); response_generator_2.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); + LOG(INFO) << "****** RESOLUTION SET FOR CHANNEL 2 *******"; WaitForServer(DEBUG_LOCATION, stub_2, 0); - gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); + LOG(INFO) << "****** CHANNEL 2 CONNECTED *******"; servers_[0]->Shutdown(); // Wait until the disconnection has triggered the connectivity notification. // Otherwise, the subchannel may be picked for next call but will fail soon. @@ -1262,11 +1261,11 @@ TEST_F(PickFirstTest, CheckStateBeforeStartWatch) { // Channel 2 will also receive a re-resolution containing the same server. // Both channels will ref the same subchannel that failed. StartServers(1, ports); - gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); - gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); + LOG(INFO) << "****** SERVER RESTARTED AGAIN *******"; + LOG(INFO) << "****** CHANNEL 2 STARTING A CALL *******"; // The first call after the server restart will succeed. CheckRpcSendOk(DEBUG_LOCATION, stub_2); - gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******"); + LOG(INFO) << "****** CHANNEL 2 FINISHED A CALL *******"; // Check LB policy name for the channel. EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName()); // Check LB policy name for the channel. @@ -1411,7 +1410,7 @@ TEST_F(RoundRobinTest, Updates) { auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); // Start with a single server. - gpr_log(GPR_INFO, "*** FIRST BACKEND ***"); + LOG(INFO) << "*** FIRST BACKEND ***"; std::vector ports = {servers_[0]->port_}; response_generator.SetNextResolution(ports); WaitForServer(DEBUG_LOCATION, stub, 0); @@ -1422,7 +1421,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(0, servers_[2]->service_.request_count()); ResetCounters(); // And now for the second server. - gpr_log(GPR_INFO, "*** SECOND BACKEND ***"); + LOG(INFO) << "*** SECOND BACKEND ***"; ports.clear(); ports.emplace_back(servers_[1]->port_); response_generator.SetNextResolution(ports); @@ -1436,7 +1435,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(0, servers_[2]->service_.request_count()); ResetCounters(); // ... and for the last server. - gpr_log(GPR_INFO, "*** THIRD BACKEND ***"); + LOG(INFO) << "*** THIRD BACKEND ***"; ports.clear(); ports.emplace_back(servers_[2]->port_); response_generator.SetNextResolution(ports); @@ -1447,7 +1446,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(10, servers_[2]->service_.request_count()); ResetCounters(); // Back to all servers. - gpr_log(GPR_INFO, "*** ALL BACKENDS ***"); + LOG(INFO) << "*** ALL BACKENDS ***"; ports.clear(); ports.emplace_back(servers_[0]->port_); ports.emplace_back(servers_[1]->port_); @@ -1461,7 +1460,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(1, servers_[2]->service_.request_count()); ResetCounters(); // An empty update will result in the channel going into TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "*** NO BACKENDS ***"); + LOG(INFO) << "*** NO BACKENDS ***"; ports.clear(); response_generator.SetNextResolution(ports); WaitForChannelNotReady(channel.get()); @@ -1469,7 +1468,7 @@ TEST_F(RoundRobinTest, Updates) { "empty address list: fake resolver empty address list"); servers_[0]->service_.ResetCounters(); // Next update introduces servers_[1], making the channel recover. - gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***"); + LOG(INFO) << "*** BACK TO SECOND BACKEND ***"; ports.clear(); ports.emplace_back(servers_[1]->port_); response_generator.SetNextResolution(ports); @@ -1550,15 +1549,15 @@ TEST_F(RoundRobinTest, ReresolveOnSubchannelConnectionFailure) { // Wait for both servers to be seen. WaitForServers(DEBUG_LOCATION, stub, 0, 2); // Have server 0 send a GOAWAY. This should trigger a re-resolution. - gpr_log(GPR_INFO, "****** SENDING GOAWAY FROM SERVER 0 *******"); + LOG(INFO) << "****** SENDING GOAWAY FROM SERVER 0 *******"; { grpc_core::ExecCtx exec_ctx; grpc_core::Server::FromC(servers_[0]->server_->c_server())->SendGoaways(); } - gpr_log(GPR_INFO, "****** WAITING FOR RE-RESOLUTION REQUEST *******"); + LOG(INFO) << "****** WAITING FOR RE-RESOLUTION REQUEST *******"; EXPECT_TRUE(response_generator.Get()->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); - gpr_log(GPR_INFO, "****** RE-RESOLUTION REQUEST SEEN *******"); + LOG(INFO) << "****** RE-RESOLUTION REQUEST SEEN *******"; // Tell the fake resolver to send an update that adds the last server, but // only when the LB policy requests re-resolution. ports.push_back(servers_[2]->port_); @@ -1571,7 +1570,7 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) { FakeResolverResponseGeneratorWrapper response_generator; auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); - gpr_log(GPR_INFO, "****** SENDING INITIAL RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING INITIAL RESOLVER RESULT *******"; // Send a resolver result with an empty address list and a callback // that triggers a notification. grpc_core::Notification notification; @@ -1585,7 +1584,7 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) { }; response_generator.SetResponse(std::move(result)); // Wait for channel to report TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "****** TELLING CHANNEL TO CONNECT *******"); + LOG(INFO) << "****** TELLING CHANNEL TO CONNECT *******"; auto predicate = [](grpc_connectivity_state state) { return state == GRPC_CHANNEL_TRANSIENT_FAILURE; }; @@ -1594,10 +1593,10 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) { // Callback should have been run. notification.WaitForNotification(); // Return a valid address. - gpr_log(GPR_INFO, "****** SENDING NEXT RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING NEXT RESOLVER RESULT *******"; StartServers(1); response_generator.SetNextResolution(GetServersPorts()); - gpr_log(GPR_INFO, "****** SENDING WAIT_FOR_READY RPC *******"); + LOG(INFO) << "****** SENDING WAIT_FOR_READY RPC *******"; CheckRpcSendOk(DEBUG_LOCATION, stub, /*wait_for_ready=*/true); } @@ -1658,7 +1657,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) { response_generator.SetNextResolution({port}); // Allow first connection attempt to fail normally, and wait for // channel to report TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO REPORT TF ==="); + LOG(INFO) << "=== WAITING FOR CHANNEL TO REPORT TF ==="; auto predicate = [](grpc_connectivity_state state) { return state == GRPC_CHANNEL_TRANSIENT_FAILURE; }; @@ -1673,7 +1672,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) { EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel->GetState(false)); // Send a few RPCs, just to give the channel a chance to propagate a // new picker, in case it was going to incorrectly do so. - gpr_log(GPR_INFO, "=== EXPECTING RPCs TO FAIL ==="); + LOG(INFO) << "=== EXPECTING RPCs TO FAIL ==="; for (size_t i = 0; i < 5; ++i) { CheckRpcSendFailure( DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE, @@ -1718,7 +1717,7 @@ TEST_F(RoundRobinTest, ReportsLatestStatusInTransientFailure) { "Survey says... Bzzzzt!"))(status.error_message())) { break; } - gpr_log(GPR_INFO, "STATUS MESSAGE: %s", status.error_message().c_str()); + LOG(INFO) << "STATUS MESSAGE: " << status.error_message(); EXPECT_THAT(status.error_message(), ::testing::MatchesRegex(MakeConnectionFailureRegex( "connections to all backends failing"))); @@ -1740,21 +1739,21 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) { auto stub = BuildStub(channel); response_generator.SetNextResolution(GetServersPorts()); // Start a thread constantly sending RPCs in a loop. - gpr_log(GPR_INFO, "=== STARTING CLIENT THREAD ==="); + LOG(INFO) << "=== STARTING CLIENT THREAD ==="; std::atomic shutdown{false}; gpr_event ev; gpr_event_init(&ev); std::thread thd([&]() { - gpr_log(GPR_INFO, "sending first RPC"); + LOG(INFO) << "sending first RPC"; CheckRpcSendOk(DEBUG_LOCATION, stub); gpr_event_set(&ev, reinterpret_cast(1)); while (!shutdown.load()) { - gpr_log(GPR_INFO, "sending RPC"); + LOG(INFO) << "sending RPC"; CheckRpcSendOk(DEBUG_LOCATION, stub); } }); // Wait for first RPC to complete. - gpr_log(GPR_INFO, "=== WAITING FOR FIRST RPC TO COMPLETE ==="); + LOG(INFO) << "=== WAITING FOR FIRST RPC TO COMPLETE ==="; ASSERT_EQ(reinterpret_cast(1), gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(1))); // Channel should now be READY. @@ -1765,7 +1764,7 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) { // Now kill the server. The subchannel should report IDLE and be // immediately reconnected to, but this should not cause any test // failures. - gpr_log(GPR_INFO, "=== SHUTTING DOWN SERVER ==="); + LOG(INFO) << "=== SHUTTING DOWN SERVER ==="; { grpc_core::ExecCtx exec_ctx; grpc_core::Server::FromC(servers_[0]->server_->c_server())->SendGoaways(); @@ -1773,17 +1772,17 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) { gpr_sleep_until(grpc_timeout_seconds_to_deadline(1)); servers_[0]->Shutdown(); // Wait for next attempt to start. - gpr_log(GPR_INFO, "=== WAITING FOR RECONNECTION ATTEMPT ==="); + LOG(INFO) << "=== WAITING FOR RECONNECTION ATTEMPT ==="; hold1->Wait(); // Start server and allow attempt to continue. - gpr_log(GPR_INFO, "=== RESTARTING SERVER ==="); + LOG(INFO) << "=== RESTARTING SERVER ==="; StartServer(0); hold1->Resume(); // Wait for next attempt to complete. - gpr_log(GPR_INFO, "=== WAITING FOR RECONNECTION ATTEMPT TO COMPLETE ==="); + LOG(INFO) << "=== WAITING FOR RECONNECTION ATTEMPT TO COMPLETE ==="; hold1->WaitForCompletion(); // Now shut down the thread. - gpr_log(GPR_INFO, "=== SHUTTING DOWN CLIENT THREAD ==="); + LOG(INFO) << "=== SHUTTING DOWN CLIENT THREAD ==="; shutdown.store(true); thd.join(); } @@ -1871,14 +1870,13 @@ TEST_F(RoundRobinTest, HealthChecking) { auto stub = BuildStub(channel); response_generator.SetNextResolution(GetServersPorts()); // Channel should not become READY, because health checks should be failing. - gpr_log(GPR_INFO, - "*** initial state: unknown health check service name for " - "all servers"); + LOG(INFO) + << "*** initial state: unknown health check service name for all servers"; EXPECT_FALSE(WaitForChannelReady(channel.get(), 1)); // Now set one of the servers to be healthy. // The channel should become healthy and all requests should go to // the healthy server. - gpr_log(GPR_INFO, "*** server 0 healthy"); + LOG(INFO) << "*** server 0 healthy"; servers_[0]->SetServingStatus("health_check_service_name", true); EXPECT_TRUE(WaitForChannelReady(channel.get())); // New channel state may be reported before the picker is updated, so @@ -1891,7 +1889,7 @@ TEST_F(RoundRobinTest, HealthChecking) { EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(0, servers_[2]->service_.request_count()); // Now set a second server to be healthy. - gpr_log(GPR_INFO, "*** server 2 healthy"); + LOG(INFO) << "*** server 2 healthy"; servers_[2]->SetServingStatus("health_check_service_name", true); WaitForServer(DEBUG_LOCATION, stub, 2); for (int i = 0; i < 10; ++i) { @@ -1901,7 +1899,7 @@ TEST_F(RoundRobinTest, HealthChecking) { EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(5, servers_[2]->service_.request_count()); // Now set the remaining server to be healthy. - gpr_log(GPR_INFO, "*** server 1 healthy"); + LOG(INFO) << "*** server 1 healthy"; servers_[1]->SetServingStatus("health_check_service_name", true); WaitForServer(DEBUG_LOCATION, stub, 1); for (int i = 0; i < 9; ++i) { @@ -1914,7 +1912,7 @@ TEST_F(RoundRobinTest, HealthChecking) { // unhealthiness has hit the client. We know that the client will see // this when we send kNumServers requests and one of the remaining servers // sees two of the requests. - gpr_log(GPR_INFO, "*** server 0 unhealthy"); + LOG(INFO) << "*** server 0 unhealthy"; servers_[0]->SetServingStatus("health_check_service_name", false); do { ResetCounters(); @@ -1925,7 +1923,7 @@ TEST_F(RoundRobinTest, HealthChecking) { servers_[2]->service_.request_count() != 2); // Now set the remaining two servers to be unhealthy. Make sure the // channel leaves READY state and that RPCs fail. - gpr_log(GPR_INFO, "*** all servers unhealthy"); + LOG(INFO) << "*** all servers unhealthy"; servers_[1]->SetServingStatus("health_check_service_name", false); servers_[2]->SetServingStatus("health_check_service_name", false); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index fa3f9936a99..ef1cfc1382d 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -27,6 +27,7 @@ #include "absl/cleanup/cleanup.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -225,7 +226,7 @@ class BalancerServiceImpl : public BalancerService { shutdown_ = true; } ShutdownStream(); - gpr_log(GPR_INFO, "LB[%p]: shut down", this); + LOG(INFO) << "LB[" << this << "]: shut down"; } void set_client_load_reporting_interval_seconds(int seconds) { @@ -285,11 +286,11 @@ class BalancerServiceImpl : public BalancerService { private: // Request handler. Status BalanceLoad(ServerContext* context, Stream* stream) override { - gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); + LOG(INFO) << "LB[" << this << "]: BalanceLoad"; { grpc_core::MutexLock lock(&mu_); if (shutdown_) { - gpr_log(GPR_INFO, "LB[%p]: shutdown at stream start", this); + LOG(INFO) << "LB[" << this << "]: shutdown at stream start"; return Status::OK; } } @@ -310,7 +311,7 @@ class BalancerServiceImpl : public BalancerService { // Read initial request. LoadBalanceRequest request; if (!stream->Read(&request)) { - gpr_log(GPR_INFO, "LB[%p]: stream read returned false", this); + LOG(INFO) << "LB[" << this << "]: stream read returned false"; return Status::OK; } EXPECT_TRUE(request.has_initial_request()); @@ -319,8 +320,8 @@ class BalancerServiceImpl : public BalancerService { service_names_.push_back(request.initial_request().name()); } IncreaseRequestCount(); - gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, - request.DebugString().c_str()); + LOG(INFO) << "LB[" << this << "]: received initial message '" + << request.DebugString() << "'"; // Send initial response. LoadBalanceResponse response; auto* initial_response = response.mutable_initial_response(); @@ -334,11 +335,11 @@ class BalancerServiceImpl : public BalancerService { std::thread reader(std::bind(&BalancerServiceImpl::ReadThread, this, stream, &reader_shutdown)); auto thread_cleanup = absl::MakeCleanup([&]() { - gpr_log(GPR_INFO, "shutting down reader thread"); + LOG(INFO) << "shutting down reader thread"; reader_shutdown.Notify(); - gpr_log(GPR_INFO, "joining reader thread"); + LOG(INFO) << "joining reader thread"; reader.join(); - gpr_log(GPR_INFO, "joining reader thread complete"); + LOG(INFO) << "joining reader thread complete"; }); // Send responses as instructed by the test. while (true) { @@ -347,12 +348,12 @@ class BalancerServiceImpl : public BalancerService { context->TryCancel(); break; } - gpr_log(GPR_INFO, "LB[%p]: Sending response: %s", this, - response->DebugString().c_str()); + LOG(INFO) << "LB[" << this + << "]: Sending response: " << response->DebugString(); IncreaseResponseCount(); stream->Write(*response); } - gpr_log(GPR_INFO, "LB[%p]: done", this); + LOG(INFO) << "LB[" << this << "]: done"; return Status::OK; } @@ -360,8 +361,8 @@ class BalancerServiceImpl : public BalancerService { void ReadThread(Stream* stream, absl::Notification* shutdown) { LoadBalanceRequest request; while (!shutdown->HasBeenNotified() && stream->Read(&request)) { - gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", - this, request.DebugString().c_str()); + LOG(INFO) << "LB[" << this << "]: received client load report message '" + << request.DebugString() << "'"; EXPECT_GT(client_load_reporting_interval_seconds_, 0); EXPECT_TRUE(request.has_client_stats()); ClientStats load_report; @@ -451,7 +452,7 @@ class GrpclbEnd2endTest : public ::testing::Test { ~ServerThread() { Shutdown(); } void Start() { - gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); + LOG(INFO) << "starting " << type_ << " server on port " << port_; CHECK(!running_); running_ = true; service_.Start(); @@ -463,7 +464,7 @@ class GrpclbEnd2endTest : public ::testing::Test { thread_ = std::make_unique( std::bind(&ServerThread::Serve, this, &mu, &cond)); cond.Wait(&mu); - gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); + LOG(INFO) << type_ << " server startup complete"; } void Serve(grpc_core::Mutex* mu, grpc_core::CondVar* cond) { @@ -481,11 +482,11 @@ class GrpclbEnd2endTest : public ::testing::Test { void Shutdown() { if (!running_) return; - gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + LOG(INFO) << type_ << " about to shutdown"; service_.Shutdown(); server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); thread_->join(); - gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + LOG(INFO) << type_ << " shutdown completed"; running_ = false; } @@ -667,8 +668,8 @@ class GrpclbEnd2endTest : public ::testing::Test { size_t start_index = 0, size_t stop_index = 0, WaitForBackendOptions options = WaitForBackendOptions(), SourceLocation location = SourceLocation()) { - gpr_log(GPR_INFO, "Waiting for backends [%" PRIuPTR ", %" PRIuPTR ")", - start_index, stop_index); + LOG(INFO) << "Waiting for backends [" << start_index << ", " << stop_index + << ")"; const absl::Time deadline = absl::Now() + absl::Seconds(options.timeout_seconds * grpc_test_slowdown_factor()); @@ -689,11 +690,11 @@ class GrpclbEnd2endTest : public ::testing::Test { SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); } ResetBackendCounters(); - gpr_log(GPR_INFO, - "Performed %d warm up requests (a multiple of %d) against the " - "backends. %d succeeded, %d failed, %d dropped.", - num_total, options.num_requests_multiple_of, num_ok, num_failure, - num_drops); + LOG(INFO) << "Performed " << num_total + << " warm up requests (a multiple of " + << options.num_requests_multiple_of << ") against the backends. " + << num_ok << " succeeded, " << num_failure << " failed, " + << num_drops << " dropped."; return std::make_tuple(num_ok, num_failure, num_drops); } @@ -1299,9 +1300,9 @@ TEST_F(GrpclbEnd2endTest, SetNextResolutionDefaultBalancer(); WaitForBackend(0); // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); @@ -1314,9 +1315,9 @@ TEST_F(GrpclbEnd2endTest, // Now tell the channel to use balancer 2. However, the stream to the // default balancer is not terminated, so the client will continue to // use it. - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + LOG(INFO) << "========= ABOUT TO UPDATE 1 =========="; SetNextResolution({balancer2->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + LOG(INFO) << "========= UPDATE 1 DONE =========="; // Now the default balancer sends backend 2. SendBalancerResponse(BuildResponseForBackends({backends_[2]->port()}, {})); WaitForBackend(2); @@ -1339,9 +1340,9 @@ TEST_F(GrpclbEnd2endTest, // Wait until the first backend is ready. WaitForBackend(0); // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); @@ -1351,15 +1352,15 @@ TEST_F(GrpclbEnd2endTest, EXPECT_EQ(0U, balancer2->service().request_count()); EXPECT_EQ(0U, balancer2->service().response_count()); // Send another address list with the same list of balancers. - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + LOG(INFO) << "========= ABOUT TO UPDATE 1 =========="; SetNextResolution({balancer_->port(), balancer2->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + LOG(INFO) << "========= UPDATE 1 DONE =========="; // Shut down the balancer stream to force the client to create a new one. // The new stream should go to the default balancer, since the // underlying connection should not have been broken. - gpr_log(GPR_INFO, "========= SHUTTING DOWN BALANCER CALL =========="); + LOG(INFO) << "========= SHUTTING DOWN BALANCER CALL =========="; balancer_->service().ShutdownStream(); - gpr_log(GPR_INFO, "========= DONE SHUTTING DOWN BALANCER CALL =========="); + LOG(INFO) << "========= DONE SHUTTING DOWN BALANCER CALL =========="; // Wait until client has created a new balancer stream. EXPECT_TRUE(balancer_->service().WaitForNewStream(1)); // Make sure there was only one client connection seen by the balancer. @@ -1383,34 +1384,34 @@ TEST_F(GrpclbEnd2endTest, BalancerDiesThenSwitchToNewBalancer) { EXPECT_EQ(0U, balancer2->service().request_count()); EXPECT_EQ(0U, balancer2->service().response_count()); // Send 10 RPCs. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); // Kill default balancer. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER *************"); + LOG(INFO) << "********** ABOUT TO KILL BALANCER *************"; balancer_->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER *************"); + LOG(INFO) << "********** KILLED BALANCER *************"; // Channel should continue using the last backend it saw from the // balancer before the balancer died. - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + LOG(INFO) << "========= BEFORE SECOND BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + LOG(INFO) << "========= DONE WITH SECOND BATCH =========="; // All 10 requests should again have gone to the first backend. EXPECT_EQ(20U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); // Tell channel to start using balancer 2. - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + LOG(INFO) << "========= ABOUT TO UPDATE 1 =========="; SetNextResolution({balancer2->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + LOG(INFO) << "========= UPDATE 1 DONE =========="; // Channel should start using backend 1. WaitForBackend(1); // This is serviced by the updated RR policy - gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + LOG(INFO) << "========= BEFORE THIRD BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + LOG(INFO) << "========= DONE WITH THIRD BATCH =========="; // All 10 requests should have gone to the second backend. EXPECT_EQ(0U, backends_[0]->service().request_count()); EXPECT_EQ(10U, backends_[1]->service().request_count()); @@ -1428,15 +1429,15 @@ TEST_F(GrpclbEnd2endTest, ReresolveDeadBackendWhileInFallback) { // responds, and a fallback backend. SetNextResolution({balancer_->port()}, {backends_[0]->port()}); // Start servers and send 10 RPCs per server. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the fallback backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); // Kill backend 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); + LOG(INFO) << "********** ABOUT TO KILL BACKEND 0 *************"; backends_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); + LOG(INFO) << "********** KILLED BACKEND 0 *************"; // This should trigger re-resolution. EXPECT_TRUE(response_generator_->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); @@ -1446,9 +1447,9 @@ TEST_F(GrpclbEnd2endTest, ReresolveDeadBackendWhileInFallback) { // Wait until re-resolution has been seen, as signaled by the second backend // receiving a request. WaitForBackend(1); - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + LOG(INFO) << "========= BEFORE SECOND BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + LOG(INFO) << "========= DONE WITH SECOND BATCH =========="; // All 10 requests should have gone to the second backend. EXPECT_EQ(10U, backends_[1]->service().request_count()); EXPECT_EQ(1U, balancer_->service().request_count()); @@ -1467,9 +1468,9 @@ TEST_F(GrpclbEnd2endTest, ReresolveWhenBalancerCallFails) { SetNextResolutionDefaultBalancer(); WaitForBackend(0); // Send 10 RPCs. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); // Balancer 0 got a single request and sent a single request. @@ -1478,13 +1479,13 @@ TEST_F(GrpclbEnd2endTest, ReresolveWhenBalancerCallFails) { EXPECT_EQ(0U, balancer2->service().request_count()); EXPECT_EQ(0U, balancer2->service().response_count()); // Kill balancer 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); + LOG(INFO) << "********** ABOUT TO KILL BALANCER 0 *************"; balancer_->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); + LOG(INFO) << "********** KILLED BALANCER 0 *************"; // This should trigger a re-resolution. EXPECT_TRUE(response_generator_->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); - gpr_log(GPR_INFO, "********** SAW RE-RESOLUTION REQUEST *************"); + LOG(INFO) << "********** SAW RE-RESOLUTION REQUEST *************"; // Re-resolution result switches to balancer 2. SetNextResolution({balancer2->port()}); // Client should start using backend 1. From 6b3a670cb0a9f711c5c10cca2d1b111919ebf547 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Wed, 8 May 2024 21:13:44 -0700 Subject: [PATCH 10/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36547) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36547 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36547 from tanvi-jagtap:test_cpp_ext_stats_plugin_tjagtap 8e80774fe17acbce4439ec95c9e8a3bf0bf3cbfa PiperOrigin-RevId: 632020672 --- test/cpp/ext/filters/census/BUILD | 1 + .../census/stats_plugin_end2end_test.cc | 182 +++++++++--------- 2 files changed, 92 insertions(+), 91 deletions(-) diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 1be8dfe81e8..967d9da6e79 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -51,6 +51,7 @@ grpc_cc_test( "stats_plugin_end2end_test.cc", ], external_deps = [ + "absl/log:log", "gtest", "opencensus-stats-test", "opencensus-tags", diff --git a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc index a700810a3ea..916718c5a7c 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -20,6 +20,7 @@ #include // NOLINT #include +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "gmock/gmock.h" @@ -517,8 +518,8 @@ TEST_F(StatsPluginEnd2EndTest, TestRetryStatsWithAdditionalRetries) { ::testing::ElementsAre(client_method_name_), ::testing::Eq(0)))); auto data = client_retry_delay_per_call_view.GetData().distribution_data(); for (const auto& entry : data) { - gpr_log(GPR_ERROR, "Mean Retry Delay %s: %lf ms", entry.first[0].c_str(), - entry.second.mean()); + LOG(ERROR) << "Mean Retry Delay " << entry.first[0] << ": " + << entry.second.mean() << " ms"; } // We expect the retry delay to be around 100ms. EXPECT_THAT( @@ -1007,95 +1008,94 @@ TEST_F(StatsPluginEnd2EndTest, TestGlobalEnableOpenCensusTracing) { // This test verifies that users depending on src/cpp/ext/filters/census header // files can continue using the non-experimental names. TEST(StatsPluginDeclarationTest, Declarations) { - gpr_log(GPR_INFO, "%p", ClientMethodTagKey); - gpr_log(GPR_INFO, "%p", ClientStatusTagKey); - gpr_log(GPR_INFO, "%p", ServerMethodTagKey); - gpr_log(GPR_INFO, "%p", ServerStatusTagKey); - - gpr_log(GPR_INFO, "%p", kRpcClientReceivedBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientReceivedMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientRetriesPerCallMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientRetryDelayPerCallMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientRoundtripLatencyMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientSentBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientSentMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientServerLatencyMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientStartedRpcsMeasureName.data()); - gpr_log(GPR_INFO, "%p", - kRpcClientTransparentRetriesPerCallMeasureName.data()); - - gpr_log(GPR_INFO, "%p", kRpcServerReceivedBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerReceivedMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerSentBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerSentMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerServerLatencyMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerStartedRpcsMeasureName.data()); - - gpr_log(GPR_INFO, "%p", ClientCompletedRpcsCumulative); - gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientRetriesCumulative); - gpr_log(GPR_INFO, "%p", ClientRetriesPerCallCumulative); - gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallCumulative); - gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyCumulative); - gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientServerLatencyCumulative); - gpr_log(GPR_INFO, "%p", ClientStartedRpcsCumulative); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesCumulative); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallCumulative); - - gpr_log(GPR_INFO, "%p", ServerCompletedRpcsCumulative); - gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerServerLatencyCumulative); - gpr_log(GPR_INFO, "%p", ServerStartedRpcsCumulative); - - gpr_log(GPR_INFO, "%p", ClientCompletedRpcsMinute); - gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientRetriesMinute); - gpr_log(GPR_INFO, "%p", ClientRetriesPerCallMinute); - gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallMinute); - gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyMinute); - gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientServerLatencyMinute); - gpr_log(GPR_INFO, "%p", ClientStartedRpcsMinute); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesMinute); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallMinute); - - gpr_log(GPR_INFO, "%p", ServerCompletedRpcsMinute); - gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerServerLatencyMinute); - gpr_log(GPR_INFO, "%p", ServerStartedRpcsMinute); - - gpr_log(GPR_INFO, "%p", ClientCompletedRpcsHour); - gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientRetriesHour); - gpr_log(GPR_INFO, "%p", ClientRetriesPerCallHour); - gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallHour); - gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyHour); - gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientServerLatencyHour); - gpr_log(GPR_INFO, "%p", ClientStartedRpcsHour); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesHour); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallHour); - - gpr_log(GPR_INFO, "%p", ServerCompletedRpcsHour); - gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerServerLatencyHour); - gpr_log(GPR_INFO, "%p", ServerStartedRpcsHour); + LOG(INFO) << ClientMethodTagKey; + LOG(INFO) << ClientStatusTagKey; + LOG(INFO) << ServerMethodTagKey; + LOG(INFO) << ServerStatusTagKey; + + LOG(INFO) << kRpcClientReceivedBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientReceivedMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientRetriesPerCallMeasureName.data(); + LOG(INFO) << kRpcClientRetryDelayPerCallMeasureName.data(); + LOG(INFO) << kRpcClientRoundtripLatencyMeasureName.data(); + LOG(INFO) << kRpcClientSentBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientSentMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientServerLatencyMeasureName.data(); + LOG(INFO) << kRpcClientStartedRpcsMeasureName.data(); + LOG(INFO) << kRpcClientTransparentRetriesPerCallMeasureName.data(); + + LOG(INFO) << kRpcServerReceivedBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerReceivedMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerSentBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerSentMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerServerLatencyMeasureName.data(); + LOG(INFO) << kRpcServerStartedRpcsMeasureName.data(); + + LOG(INFO) << ClientCompletedRpcsCumulative; + LOG(INFO) << ClientReceivedBytesPerRpcCumulative; + LOG(INFO) << ClientReceivedMessagesPerRpcCumulative; + LOG(INFO) << ClientRetriesCumulative; + LOG(INFO) << ClientRetriesPerCallCumulative; + LOG(INFO) << ClientRetryDelayPerCallCumulative; + LOG(INFO) << ClientRoundtripLatencyCumulative; + LOG(INFO) << ClientSentBytesPerRpcCumulative; + LOG(INFO) << ClientSentMessagesPerRpcCumulative; + LOG(INFO) << ClientServerLatencyCumulative; + LOG(INFO) << ClientStartedRpcsCumulative; + LOG(INFO) << ClientTransparentRetriesCumulative; + LOG(INFO) << ClientTransparentRetriesPerCallCumulative; + + LOG(INFO) << ServerCompletedRpcsCumulative; + LOG(INFO) << ServerReceivedBytesPerRpcCumulative; + LOG(INFO) << ServerReceivedMessagesPerRpcCumulative; + LOG(INFO) << ServerSentBytesPerRpcCumulative; + LOG(INFO) << ServerSentMessagesPerRpcCumulative; + LOG(INFO) << ServerServerLatencyCumulative; + LOG(INFO) << ServerStartedRpcsCumulative; + + LOG(INFO) << ClientCompletedRpcsMinute; + LOG(INFO) << ClientReceivedBytesPerRpcMinute; + LOG(INFO) << ClientReceivedMessagesPerRpcMinute; + LOG(INFO) << ClientRetriesMinute; + LOG(INFO) << ClientRetriesPerCallMinute; + LOG(INFO) << ClientRetryDelayPerCallMinute; + LOG(INFO) << ClientRoundtripLatencyMinute; + LOG(INFO) << ClientSentBytesPerRpcMinute; + LOG(INFO) << ClientSentMessagesPerRpcMinute; + LOG(INFO) << ClientServerLatencyMinute; + LOG(INFO) << ClientStartedRpcsMinute; + LOG(INFO) << ClientTransparentRetriesMinute; + LOG(INFO) << ClientTransparentRetriesPerCallMinute; + + LOG(INFO) << ServerCompletedRpcsMinute; + LOG(INFO) << ServerReceivedBytesPerRpcMinute; + LOG(INFO) << ServerReceivedMessagesPerRpcMinute; + LOG(INFO) << ServerSentBytesPerRpcMinute; + LOG(INFO) << ServerSentMessagesPerRpcMinute; + LOG(INFO) << ServerServerLatencyMinute; + LOG(INFO) << ServerStartedRpcsMinute; + + LOG(INFO) << ClientCompletedRpcsHour; + LOG(INFO) << ClientReceivedBytesPerRpcHour; + LOG(INFO) << ClientReceivedMessagesPerRpcHour; + LOG(INFO) << ClientRetriesHour; + LOG(INFO) << ClientRetriesPerCallHour; + LOG(INFO) << ClientRetryDelayPerCallHour; + LOG(INFO) << ClientRoundtripLatencyHour; + LOG(INFO) << ClientSentBytesPerRpcHour; + LOG(INFO) << ClientSentMessagesPerRpcHour; + LOG(INFO) << ClientServerLatencyHour; + LOG(INFO) << ClientStartedRpcsHour; + LOG(INFO) << ClientTransparentRetriesHour; + LOG(INFO) << ClientTransparentRetriesPerCallHour; + + LOG(INFO) << ServerCompletedRpcsHour; + LOG(INFO) << ServerReceivedBytesPerRpcHour; + LOG(INFO) << ServerReceivedMessagesPerRpcHour; + LOG(INFO) << ServerSentBytesPerRpcHour; + LOG(INFO) << ServerSentMessagesPerRpcHour; + LOG(INFO) << ServerServerLatencyHour; + LOG(INFO) << ServerStartedRpcsHour; } } // namespace From a3aa81e179c49d26d2604fcc4ffb97a099b6602f Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap Date: Wed, 8 May 2024 21:35:00 -0700 Subject: [PATCH 11/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging GPR_ASSERT Ban GPR_ASSERT and GPR_DEBUG_ASSERT. These macros are deprecated and should be replaced with absl CHECK and absl DCHECK, respectively. PiperOrigin-RevId: 632024499 --- tools/run_tests/sanity/core_banned_functions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 7804dd0fe52..806f3c806b6 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -82,8 +82,8 @@ BANNED_EXCEPT = { "src/core/load_balancing/rls/rls.cc", "src/core/resolver/google_c2p/google_c2p_resolver.cc", ], - # use 'grpc_core::Crash' instead - "GPR_ASSERT(false": [], + # use 'absl CHECK' instead + "GPR_ASSERT": [], # Use `std::exchange()` instead. "absl::exchange": [], # Use `std::make_unique()` instead. From d8d7128d2d120a6467ba8622c8367dab20c2c7cc Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Wed, 8 May 2024 21:37:04 -0700 Subject: [PATCH 12/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36550) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36550 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36550 from tanvi-jagtap:tjagtap_test_cpp_e2e_xds d242076993e6f82886f91cf53f7abdb0c88e7424 PiperOrigin-RevId: 632024853 --- test/cpp/end2end/xds/BUILD | 6 +- .../end2end/xds/xds_ring_hash_end2end_test.cc | 33 ++++---- test/cpp/end2end/xds/xds_server.h | 84 +++++++++---------- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/test/cpp/end2end/xds/BUILD b/test/cpp/end2end/xds/BUILD index 5dd690f6a7b..15afd38eb26 100644 --- a/test/cpp/end2end/xds/BUILD +++ b/test/cpp/end2end/xds/BUILD @@ -25,7 +25,10 @@ grpc_cc_library( name = "xds_server", srcs = ["xds_server.cc"], hdrs = ["xds_server.h"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], visibility = ["@grpc:xds_end2end_test_utils"], deps = [ "//:gpr", @@ -349,6 +352,7 @@ grpc_cc_test( srcs = ["xds_ring_hash_end2end_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], flaky = True, # TODO(b/144705388) diff --git a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc index 84dc4865661..70188884d2e 100644 --- a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc @@ -20,6 +20,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -313,14 +314,14 @@ TEST_P(RingHashTest, // Allow the connection attempt to complete. hold->Resume(); // Now the RPCs should complete successfully. - gpr_log(GPR_INFO, "=== WAITING FOR FIRST RPC TO FINISH ==="); + LOG(INFO) << "=== WAITING FOR FIRST RPC TO FINISH ==="; Status status = rpc.GetStatus(); - gpr_log(GPR_INFO, "=== FIRST RPC FINISHED ==="); + LOG(INFO) << "=== FIRST RPC FINISHED ==="; EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); - gpr_log(GPR_INFO, "=== WAITING FOR SECOND RPC TO FINISH ==="); + LOG(INFO) << "=== WAITING FOR SECOND RPC TO FINISH ==="; status = rpc2.GetStatus(); - gpr_log(GPR_INFO, "=== SECOND RPC FINISHED ==="); + LOG(INFO) << "=== SECOND RPC FINISHED ==="; EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); } @@ -1033,24 +1034,24 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) { .set_metadata(std::move(metadata)) .set_timeout_ms(kConnectionTimeoutMilliseconds); EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false)); - gpr_log(GPR_INFO, "=== SENDING FIRST RPC ==="); + LOG(INFO) << "=== SENDING FIRST RPC ==="; CheckRpcSendFailure( DEBUG_LOCATION, StatusCode::UNAVAILABLE, MakeConnectionFailureRegex( "ring hash cannot find a connected endpoint; first failure: "), rpc_options); - gpr_log(GPR_INFO, "=== DONE WITH FIRST RPC ==="); + LOG(INFO) << "=== DONE WITH FIRST RPC ==="; EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel_->GetState(false)); // Bring up backend 0. The channel should become connected without // any picks, because in TF, we are always trying to connect to at // least one backend at all times. - gpr_log(GPR_INFO, "=== STARTING BACKEND 0 ==="); + LOG(INFO) << "=== STARTING BACKEND 0 ==="; StartBackend(0); - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO BECOME READY ==="); + LOG(INFO) << "=== WAITING FOR CHANNEL TO BECOME READY ==="; EXPECT_TRUE(channel_->WaitForConnected( grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds))); // RPCs should go to backend 0. - gpr_log(GPR_INFO, "=== WAITING FOR BACKEND 0 ==="); + LOG(INFO) << "=== WAITING FOR BACKEND 0 ==="; WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr, WaitForBackendOptions(), rpc_options); EXPECT_EQ(GRPC_CHANNEL_READY, channel_->GetState(false)); @@ -1062,28 +1063,28 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) { // Since the the entries in the ring are pretty distributed and we have // unused ports to fill the ring, it is almost guaranteed that the Picker // will go through some non-READY entries and skip them as per design. - gpr_log(GPR_INFO, "=== SHUTTING DOWN BACKEND 0 ==="); + LOG(INFO) << "=== SHUTTING DOWN BACKEND 0 ==="; ShutdownBackend(0); - gpr_log(GPR_INFO, "=== WAITING FOR STATE CHANGE ==="); + LOG(INFO) << "=== WAITING FOR STATE CHANGE ==="; EXPECT_TRUE(channel_->WaitForStateChange( GRPC_CHANNEL_READY, grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds))); EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel_->GetState(false)); - gpr_log(GPR_INFO, "=== SENDING SECOND RPC ==="); + LOG(INFO) << "=== SENDING SECOND RPC ==="; CheckRpcSendFailure( DEBUG_LOCATION, StatusCode::UNAVAILABLE, MakeConnectionFailureRegex( "ring hash cannot find a connected endpoint; first failure: "), rpc_options); - gpr_log(GPR_INFO, "=== STARTING BACKEND 1 ==="); + LOG(INFO) << "=== STARTING BACKEND 1 ==="; StartBackend(1); - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO BECOME READY ==="); + LOG(INFO) << "=== WAITING FOR CHANNEL TO BECOME READY ==="; EXPECT_TRUE(channel_->WaitForConnected( grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds))); - gpr_log(GPR_INFO, "=== WAITING FOR BACKEND 1 ==="); + LOG(INFO) << "=== WAITING FOR BACKEND 1 ==="; WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr, WaitForBackendOptions(), rpc_options); - gpr_log(GPR_INFO, "=== DONE ==="); + LOG(INFO) << "=== DONE ==="; } // This tests a bug seen in the wild where ring_hash started with no diff --git a/test/cpp/end2end/xds/xds_server.h b/test/cpp/end2end/xds/xds_server.h index 1fa7d0cf3dd..20372a2a3be 100644 --- a/test/cpp/end2end/xds/xds_server.h +++ b/test/cpp/end2end/xds/xds_server.h @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/types/optional.h" #include @@ -233,16 +234,16 @@ class AdsServiceImpl Status StreamAggregatedResources(ServerContext* context, Stream* stream) override { - gpr_log(GPR_INFO, "ADS[%s]: StreamAggregatedResources starts", - debug_label_.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: StreamAggregatedResources starts"; { grpc_core::MutexLock lock(&ads_mu_); if (forced_ads_failure_.has_value()) { - gpr_log(GPR_INFO, - "ADS[%s]: StreamAggregatedResources forcing early failure " - "with status code: %d, message: %s", - debug_label_.c_str(), forced_ads_failure_.value().error_code(), - forced_ads_failure_.value().error_message().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: StreamAggregatedResources forcing early failure " + "with status code: " + << forced_ads_failure_.value().error_code() << ", message: " + << forced_ads_failure_.value().error_message(); return forced_ads_failure_.value(); } } @@ -283,10 +284,9 @@ class AdsServiceImpl DiscoveryRequest request = std::move(requests.front()); requests.pop_front(); did_work = true; - gpr_log(GPR_INFO, - "ADS[%s]: Received request for type %s with content %s", - debug_label_.c_str(), request.type_url().c_str(), - request.DebugString().c_str()); + LOG(INFO) << "ADS[" << debug_label_ << "]: Received request for type " + << request.type_url() << " with content " + << request.DebugString(); SentState& sent_state = sent_state_map[request.type_url()]; // Process request. ProcessRequest(request, &update_queue, &subscription_map, &sent_state, @@ -294,8 +294,8 @@ class AdsServiceImpl } } if (response.has_value()) { - gpr_log(GPR_INFO, "ADS[%s]: Sending response: %s", debug_label_.c_str(), - response->DebugString().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending response: " << response->DebugString(); stream->Write(response.value()); } response.reset(); @@ -315,8 +315,8 @@ class AdsServiceImpl } } if (response.has_value()) { - gpr_log(GPR_INFO, "ADS[%s]: Sending update response: %s", - debug_label_.c_str(), response->DebugString().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending update response: " << response->DebugString(); stream->Write(response.value()); } { @@ -350,8 +350,7 @@ class AdsServiceImpl } } } - gpr_log(GPR_INFO, "ADS[%s]: StreamAggregatedResources done", - debug_label_.c_str()); + LOG(INFO) << "ADS[" << debug_label_ << "]: StreamAggregatedResources done"; RemoveClient(context->peer()); return Status::OK; } @@ -382,9 +381,9 @@ class AdsServiceImpl ResponseState response_state; if (!request.has_error_detail()) { response_state.state = ResponseState::ACKED; - gpr_log(GPR_INFO, "ADS[%s]: client ACKed resource_type=%s version=%s", - debug_label_.c_str(), request.type_url().c_str(), - request.version_info().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: client ACKed resource_type=" << request.type_url() + << " version=" << request.version_info(); } else { response_state.state = ResponseState::NACKED; if (check_nack_status_code_ != nullptr) { @@ -392,11 +391,10 @@ class AdsServiceImpl static_cast(request.error_detail().code())); } response_state.error_message = request.error_detail().message(); - gpr_log(GPR_INFO, - "ADS[%s]: client NACKed resource_type=%s version=%s: %s", - debug_label_.c_str(), request.type_url().c_str(), - request.version_info().c_str(), - response_state.error_message.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: client NACKed resource_type=" << request.type_url() + << " version=" << request.version_info() << ": " + << response_state.error_message; } resource_type_response_state_[request.type_url()].emplace_back( std::move(response_state)); @@ -426,9 +424,9 @@ class AdsServiceImpl &resource_state, update_queue) || ClientNeedsResourceUpdate(resource_type_state, resource_state, sent_state->resource_type_version)) { - gpr_log(GPR_INFO, "ADS[%s]: Sending update for type=%s name=%s", - debug_label_.c_str(), request.type_url().c_str(), - resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending update for type=" << request.type_url() + << " name=" << resource_name; resources_added_to_response.emplace(resource_name); if (!response->has_value()) response->emplace(); if (resource_state.resource.has_value()) { @@ -441,10 +439,9 @@ class AdsServiceImpl } } } else { - gpr_log(GPR_INFO, - "ADS[%s]: client does not need update for type=%s name=%s", - debug_label_.c_str(), request.type_url().c_str(), - resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: client does not need update for type=" + << request.type_url() << " name=" << resource_name; } } // Process unsubscriptions for any resource no longer @@ -467,8 +464,9 @@ class AdsServiceImpl SubscriptionMap* subscription_map, SentState* sent_state, absl::optional* response) ABSL_EXCLUSIVE_LOCKS_REQUIRED(ads_mu_) { - gpr_log(GPR_INFO, "ADS[%s]: Received update for type=%s name=%s", - debug_label_.c_str(), resource_type.c_str(), resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Received update for type=" << resource_type + << " name=" << resource_name; auto& subscription_name_map = (*subscription_map)[resource_type]; auto& resource_type_state = resource_map_[resource_type]; auto& resource_name_map = resource_type_state.resource_name_map; @@ -477,9 +475,9 @@ class AdsServiceImpl ResourceState& resource_state = resource_name_map[resource_name]; if (ClientNeedsResourceUpdate(resource_type_state, resource_state, sent_state->resource_type_version)) { - gpr_log(GPR_INFO, "ADS[%s]: Sending update for type=%s name=%s", - debug_label_.c_str(), resource_type.c_str(), - resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending update for type=" << resource_type + << " name=" << resource_name; response->emplace(); if (resource_state.resource.has_value()) { auto* resource = (*response)->add_resources(); @@ -510,8 +508,7 @@ class AdsServiceImpl requests->emplace_back(std::move(request)); } } - gpr_log(GPR_INFO, "ADS[%s]: Null read, stream closed", - debug_label_.c_str()); + LOG(INFO) << "ADS[" << debug_label_ << "]: Null read, stream closed"; grpc_core::MutexLock lock(&ads_mu_); *stream_closed = true; } @@ -751,7 +748,7 @@ class LrsServiceImpl using Stream = ServerReaderWriter; Status StreamLoadStats(ServerContext* /*context*/, Stream* stream) override { - gpr_log(GPR_INFO, "LRS[%s]: StreamLoadStats starts", debug_label_.c_str()); + LOG(INFO) << "LRS[" << debug_label_ << "]: StreamLoadStats starts"; if (stream_started_callback_ != nullptr) stream_started_callback_(); // Take a reference of the LrsServiceImpl object, reference will go // out of scope after this method exits. @@ -778,8 +775,9 @@ class LrsServiceImpl // Wait for report. request.Clear(); while (stream->Read(&request)) { - gpr_log(GPR_INFO, "LRS[%s]: received client load report message: %s", - debug_label_.c_str(), request.DebugString().c_str()); + LOG(INFO) << "LRS[" << debug_label_ + << "]: received client load report message: " + << request.DebugString(); std::vector stats; for (const auto& cluster_stats : request.cluster_stats()) { stats.emplace_back(cluster_stats); @@ -796,7 +794,7 @@ class LrsServiceImpl lrs_cv_.Wait(&lrs_mu_); } } - gpr_log(GPR_INFO, "LRS[%s]: StreamLoadStats done", debug_label_.c_str()); + LOG(INFO) << "LRS[" << debug_label_ << "]: StreamLoadStats done"; return Status::OK; } From ede35955a6f6cd1910e8ed33a25888fc474de26a Mon Sep 17 00:00:00 2001 From: AJ Heller Date: Thu, 9 May 2024 12:25:42 -0700 Subject: [PATCH 13/33] [EventEngine] Enable Windows EventEngine client in production builds (#36572) This has been stable in CI since May 1st (over a week), zero flakes in EE client-enabled end2end tests. Closes #36572 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36572 from drfloob:enable-win-ee-client 8f733316ee2a557c18bce5133ef6d8343315103b PiperOrigin-RevId: 632233766 --- bazel/experiments.bzl | 8 ++++---- src/core/lib/experiments/experiments.cc | 2 +- src/core/lib/experiments/experiments.h | 3 ++- src/core/lib/experiments/rollouts.yaml | 4 +--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/bazel/experiments.bzl b/bazel/experiments.bzl index abd1166647f..096b07c8828 100644 --- a/bazel/experiments.bzl +++ b/bazel/experiments.bzl @@ -60,16 +60,12 @@ EXPERIMENTS = { }, "off": { "core_end2end_test": [ - "event_engine_client", "promise_based_server_call", ], "endpoint_test": [ "tcp_frame_size_tuning", "tcp_rcv_lowat", ], - "event_engine_client_test": [ - "event_engine_client", - ], "flow_control_test": [ "multiping", "peer_state_based_framing", @@ -87,11 +83,15 @@ EXPERIMENTS = { }, "on": { "core_end2end_test": [ + "event_engine_client", "event_engine_listener", ], "cpp_lb_end2end_test": [ "pick_first_new", ], + "event_engine_client_test": [ + "event_engine_client", + ], "event_engine_listener_test": [ "event_engine_listener", ], diff --git a/src/core/lib/experiments/experiments.cc b/src/core/lib/experiments/experiments.cc index 3f9e6a840ca..c5e2d3fb3b9 100644 --- a/src/core/lib/experiments/experiments.cc +++ b/src/core/lib/experiments/experiments.cc @@ -358,7 +358,7 @@ const ExperimentMetadata g_experiment_metadata[] = { {"client_privacy", description_client_privacy, additional_constraints_client_privacy, nullptr, 0, false, false}, {"event_engine_client", description_event_engine_client, - additional_constraints_event_engine_client, nullptr, 0, false, true}, + additional_constraints_event_engine_client, nullptr, 0, true, true}, {"event_engine_dns", description_event_engine_dns, additional_constraints_event_engine_dns, nullptr, 0, false, false}, {"event_engine_listener", description_event_engine_listener, diff --git a/src/core/lib/experiments/experiments.h b/src/core/lib/experiments/experiments.h index faf13fca4cf..65fb7ebfa80 100644 --- a/src/core/lib/experiments/experiments.h +++ b/src/core/lib/experiments/experiments.h @@ -100,7 +100,8 @@ inline bool IsCallStatusOverrideOnCancellationEnabled() { return true; } inline bool IsCallV3Enabled() { return false; } inline bool IsCanaryClientPrivacyEnabled() { return false; } inline bool IsClientPrivacyEnabled() { return false; } -inline bool IsEventEngineClientEnabled() { return false; } +#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_CLIENT +inline bool IsEventEngineClientEnabled() { return true; } inline bool IsEventEngineDnsEnabled() { return false; } #define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_LISTENER inline bool IsEventEngineListenerEnabled() { return true; } diff --git a/src/core/lib/experiments/rollouts.yaml b/src/core/lib/experiments/rollouts.yaml index 6f4e84827f0..f9d968d62a2 100644 --- a/src/core/lib/experiments/rollouts.yaml +++ b/src/core/lib/experiments/rollouts.yaml @@ -58,9 +58,7 @@ # not tested on iOS at all ios: broken posix: false - # TODO(hork): resolve when the client end2end test flake rate reduces to - # a tolerable amount. - windows: false + windows: true - name: event_engine_dns default: # not tested on iOS at all From c0208416b6424ea2c2ee8d6c024916d19b1adf8e Mon Sep 17 00:00:00 2001 From: AJ Heller Date: Thu, 9 May 2024 12:51:50 -0700 Subject: [PATCH 14/33] Automated rollback of commit 82e5116fb0d7b66570c3a8e8bdd7651646ab7a31. PiperOrigin-RevId: 632241053 --- BUILD | 7 +- CMakeLists.txt | 6 + Makefile | 1 + Package.swift | 1 + build_autogenerated.yaml | 7 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 1 + grpc.gemspec | 1 + include/grpc/module.modulemap | 1 + include/grpc/passive_listener.h | 62 ++++ include/grpcpp/passive_listener.h | 27 ++ include/grpcpp/security/server_credentials.h | 1 + include/grpcpp/server_builder.h | 28 ++ package.xml | 1 + src/core/BUILD | 2 + .../transport/binder/server/binder_server.cc | 7 +- .../server/chaotic_good_server.cc | 7 +- .../chaotic_good/server/chaotic_good_server.h | 4 +- .../transport/chttp2/server/chttp2_server.cc | 296 ++++++++++++------ .../transport/chttp2/server/chttp2_server.h | 33 ++ .../lib/event_engine/extensions/supports_fd.h | 7 + .../event_engine/posix_engine/posix_engine.cc | 16 + .../event_engine/posix_engine/posix_engine.h | 2 + src/core/server/server.h | 14 +- src/cpp/server/server_builder.cc | 60 ++++ .../event_engine/event_engine_test_utils.h | 65 ++++ test/cpp/server/BUILD | 1 + test/cpp/server/server_builder_test.cc | 55 ++++ .../distrib/check_namespace_qualification.py | 4 + .../check_redundant_namespace_qualifiers.py | 9 + tools/doxygen/Doxyfile.c++ | 2 + tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 34 files changed, 619 insertions(+), 114 deletions(-) create mode 100644 include/grpc/passive_listener.h create mode 100644 include/grpcpp/passive_listener.h diff --git a/BUILD b/BUILD index 81e1ad65cd1..55bb4f4a347 100644 --- a/BUILD +++ b/BUILD @@ -296,6 +296,7 @@ GRPC_PUBLIC_HDRS = [ "include/grpc/grpc_posix.h", "include/grpc/grpc_security.h", "include/grpc/grpc_security_constants.h", + "include/grpc/passive_listener.h", "include/grpc/slice.h", "include/grpc/slice_buffer.h", "include/grpc/status.h", @@ -457,6 +458,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/impl/service_type.h", "include/grpcpp/impl/status.h", "include/grpcpp/impl/sync.h", + "include/grpcpp/passive_listener.h", "include/grpcpp/resource_quota.h", "include/grpcpp/security/audit_logging.h", "include/grpcpp/security/tls_crl_provider.h", @@ -883,7 +885,7 @@ grpc_cc_library( grpc_cc_library( name = "grpc_public_hdrs", - hdrs = GRPC_PUBLIC_HDRS, + hdrs = GRPC_PUBLIC_HDRS + GRPC_PUBLIC_EVENT_ENGINE_HDRS, external_deps = [ "absl/status:statusor", "absl/strings", @@ -2508,6 +2510,7 @@ grpc_cc_library( "//src/core:grpc_backend_metric_provider", "//src/core:grpc_crl_provider", "//src/core:grpc_service_config", + "//src/core:grpc_transport_chttp2_server", "//src/core:grpc_transport_inproc", "//src/core:json", "//src/core:json_reader", @@ -2566,6 +2569,7 @@ grpc_cc_library( "grpc_security_base", "grpc_service_config_impl", "grpc_trace", + "grpc_transport_chttp2", "grpc_unsecure", "grpcpp_backend_metric_recorder", "grpcpp_call_metric_recorder", @@ -2587,6 +2591,7 @@ grpc_cc_library( "//src/core:grpc_backend_metric_provider", "//src/core:grpc_insecure_credentials", "//src/core:grpc_service_config", + "//src/core:grpc_transport_chttp2_server", "//src/core:grpc_transport_inproc", "//src/core:ref_counted", "//src/core:resource_quota", diff --git a/CMakeLists.txt b/CMakeLists.txt index 787db67baa0..449d17ec767 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2746,6 +2746,7 @@ foreach(_hdr include/grpc/impl/propagation_bits.h include/grpc/impl/slice_type.h include/grpc/load_reporting.h + include/grpc/passive_listener.h include/grpc/slice.h include/grpc/slice_buffer.h include/grpc/status.h @@ -3446,6 +3447,7 @@ foreach(_hdr include/grpc/impl/propagation_bits.h include/grpc/impl/slice_type.h include/grpc/load_reporting.h + include/grpc/passive_listener.h include/grpc/slice.h include/grpc/slice_buffer.h include/grpc/status.h @@ -4314,6 +4316,7 @@ foreach(_hdr include/grpcpp/impl/service_type.h include/grpcpp/impl/status.h include/grpcpp/impl/sync.h + include/grpcpp/passive_listener.h include/grpcpp/resource_quota.h include/grpcpp/security/audit_logging.h include/grpcpp/security/auth_context.h @@ -5054,6 +5057,7 @@ foreach(_hdr include/grpcpp/impl/service_type.h include/grpcpp/impl/status.h include/grpcpp/impl/sync.h + include/grpcpp/passive_listener.h include/grpcpp/resource_quota.h include/grpcpp/security/audit_logging.h include/grpcpp/security/auth_context.h @@ -5504,6 +5508,7 @@ foreach(_hdr include/grpc/impl/propagation_bits.h include/grpc/impl/slice_type.h include/grpc/load_reporting.h + include/grpc/passive_listener.h include/grpc/slice.h include/grpc/slice_buffer.h include/grpc/status.h @@ -26833,6 +26838,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.h + test/core/event_engine/event_engine_test_utils.cc test/core/test_util/cmdline.cc test/core/test_util/fuzzer_util.cc test/core/test_util/grpc_profiler.cc diff --git a/Makefile b/Makefile index a62edd7fca3..25ebda3f986 100644 --- a/Makefile +++ b/Makefile @@ -1775,6 +1775,7 @@ PUBLIC_HEADERS_C += \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ + include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ diff --git a/Package.swift b/Package.swift index 9a1f76a9dc2..81f99552ac2 100644 --- a/Package.swift +++ b/Package.swift @@ -93,6 +93,7 @@ let package = Package( "include/grpc/impl/propagation_bits.h", "include/grpc/impl/slice_type.h", "include/grpc/load_reporting.h", + "include/grpc/passive_listener.h", "include/grpc/slice.h", "include/grpc/slice_buffer.h", "include/grpc/status.h", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index dd845a6d959..d15f905f347 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -198,6 +198,7 @@ libs: - include/grpc/impl/propagation_bits.h - include/grpc/impl/slice_type.h - include/grpc/load_reporting.h + - include/grpc/passive_listener.h - include/grpc/slice.h - include/grpc/slice_buffer.h - include/grpc/status.h @@ -2182,6 +2183,7 @@ libs: - include/grpc/impl/propagation_bits.h - include/grpc/impl/slice_type.h - include/grpc/load_reporting.h + - include/grpc/passive_listener.h - include/grpc/slice.h - include/grpc/slice_buffer.h - include/grpc/status.h @@ -3786,6 +3788,7 @@ libs: - include/grpcpp/impl/service_type.h - include/grpcpp/impl/status.h - include/grpcpp/impl/sync.h + - include/grpcpp/passive_listener.h - include/grpcpp/resource_quota.h - include/grpcpp/security/audit_logging.h - include/grpcpp/security/auth_context.h @@ -4213,6 +4216,7 @@ libs: - include/grpcpp/impl/service_type.h - include/grpcpp/impl/status.h - include/grpcpp/impl/sync.h + - include/grpcpp/passive_listener.h - include/grpcpp/resource_quota.h - include/grpcpp/security/audit_logging.h - include/grpcpp/security/auth_context.h @@ -4361,6 +4365,7 @@ libs: - include/grpc/impl/propagation_bits.h - include/grpc/impl/slice_type.h - include/grpc/load_reporting.h + - include/grpc/passive_listener.h - include/grpc/slice.h - include/grpc/slice_buffer.h - include/grpc/status.h @@ -17784,6 +17789,7 @@ targets: build: test language: c++ headers: + - test/core/event_engine/event_engine_test_utils.h - test/core/test_util/cmdline.h - test/core/test_util/evaluate_args_test_util.h - test/core/test_util/fuzzer_util.h @@ -17799,6 +17805,7 @@ targets: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/simple_messages.proto - src/proto/grpc/testing/xds/v3/orca_load_report.proto + - test/core/event_engine/event_engine_test_utils.cc - test/core/test_util/cmdline.cc - test/core/test_util/fuzzer_util.cc - test/core/test_util/grpc_profiler.cc diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 94651c55feb..ec37a7d2469 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -176,6 +176,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/service_type.h', 'include/grpcpp/impl/status.h', 'include/grpcpp/impl/sync.h', + 'include/grpcpp/passive_listener.h', 'include/grpcpp/resource_quota.h', 'include/grpcpp/security/audit_logging.h', 'include/grpcpp/security/auth_context.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4e6d835dc2a..5459da7206f 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -168,6 +168,7 @@ Pod::Spec.new do |s| 'include/grpc/impl/propagation_bits.h', 'include/grpc/impl/slice_type.h', 'include/grpc/load_reporting.h', + 'include/grpc/passive_listener.h', 'include/grpc/slice.h', 'include/grpc/slice_buffer.h', 'include/grpc/status.h', diff --git a/grpc.gemspec b/grpc.gemspec index 53f5845e405..44f58db3185 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -99,6 +99,7 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/impl/propagation_bits.h ) s.files += %w( include/grpc/impl/slice_type.h ) s.files += %w( include/grpc/load_reporting.h ) + s.files += %w( include/grpc/passive_listener.h ) s.files += %w( include/grpc/slice.h ) s.files += %w( include/grpc/slice_buffer.h ) s.files += %w( include/grpc/status.h ) diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap index c9219532826..30427e21d05 100644 --- a/include/grpc/module.modulemap +++ b/include/grpc/module.modulemap @@ -38,6 +38,7 @@ header "byte_buffer.h" header "impl/propagation_bits.h" header "impl/slice_type.h" header "load_reporting.h" + header "passive_listener.h" header "slice.h" header "slice_buffer.h" header "status.h" diff --git a/include/grpc/passive_listener.h b/include/grpc/passive_listener.h new file mode 100644 index 00000000000..fffc789dba0 --- /dev/null +++ b/include/grpc/passive_listener.h @@ -0,0 +1,62 @@ +// Copyright 2024 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_PASSIVE_LISTENER_H +#define GRPC_PASSIVE_LISTENER_H + +#include + +#include +#include +// #include + +namespace grpc_core { +class Server; + +namespace experimental { +class PassiveListenerImpl; + +/// -- EXPERIMENTAL API -- +/// Interface for used for Server Endpoint injection. +class PassiveListener { + public: + virtual ~PassiveListener() = default; + /// -- EXPERIMENTAL API -- + /// + /// Takes an Endpoint for an established connection, and treats it as if the + /// connection had been accepted by the server. + /// + /// The server must be started before endpoints can be accepted. + virtual absl::Status AcceptConnectedEndpoint( + std::unique_ptr + endpoint) = 0; + + /// -- EXPERIMENTAL API -- + /// + /// Takes a connected file descriptor, and treats it as if the server had + /// accepted the connection itself. + /// + /// Returns a failure status if the server's active EventEngine does not + /// support Endpoint creation from fds. + virtual absl::Status AcceptConnectedFd(int fd) = 0; +}; + +} // namespace experimental +} // namespace grpc_core + +absl::Status grpc_server_add_passive_listener( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener); + +#endif /* GRPC_PASSIVE_LISTENER_H */ diff --git a/include/grpcpp/passive_listener.h b/include/grpcpp/passive_listener.h new file mode 100644 index 00000000000..8def9592b5e --- /dev/null +++ b/include/grpcpp/passive_listener.h @@ -0,0 +1,27 @@ +// Copyright 2024 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 GRPCPP_PASSIVE_LISTENER_H +#define GRPCPP_PASSIVE_LISTENER_H + +#include + +namespace grpc { +namespace experimental { + +using grpc_core::experimental::PassiveListener; + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_PASSIVE_LISTENER_H diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index fe8c546190d..e3f5c2bbbfe 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -84,6 +84,7 @@ class ServerCredentials : private grpc::internal::GrpcLibrary { // Needed for access to AddPortToServer. friend class Server; // Needed for access to c_creds_. + friend class ServerBuilder; friend std::shared_ptr grpc::XdsServerCredentials( const std::shared_ptr& fallback_credentials); diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index e6266a90d98..e66ca4301cd 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -25,13 +25,17 @@ #include #include +#include +#include #include #include #include #include #include #include +#include #include +#include #include #include #include @@ -291,6 +295,18 @@ class ServerBuilder { void EnableCallMetricRecording( experimental::ServerMetricRecorder* server_metric_recorder = nullptr); + // Creates a passive listener for Server Endpoint injection. + /// + /// \a PasiveListener lets applications provide pre-established connections + /// to gRPC Servers. The server will behave as if it accepted the connection + /// itself on its own listening addresses. + /// + /// This can be called multiple times to create passive listeners with + /// different server credentials. + ServerBuilder& AddPassiveListener( + std::shared_ptr creds, + std::unique_ptr& passive_listener); + private: ServerBuilder* builder_; }; @@ -364,6 +380,17 @@ class ServerBuilder { private: friend class grpc::testing::ServerBuilderPluginTest; + struct UnstartedPassiveListener { + std::weak_ptr + passive_listener; + std::shared_ptr credentials; + UnstartedPassiveListener( + std::weak_ptr listener, + std::shared_ptr creds) + : passive_listener(std::move(listener)), + credentials(std::move(creds)) {} + }; + struct SyncServerSettings { SyncServerSettings() : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} @@ -388,6 +415,7 @@ class ServerBuilder { std::vector> options_; std::vector> services_; std::vector ports_; + std::vector unstarted_passive_listeners_; SyncServerSettings sync_server_settings_; diff --git a/package.xml b/package.xml index e7600613939..70f64915ef8 100644 --- a/package.xml +++ b/package.xml @@ -81,6 +81,7 @@ + diff --git a/src/core/BUILD b/src/core/BUILD index ec15ddb027c..ddb7e1d6669 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -6892,6 +6892,8 @@ grpc_cc_library( "connection_quota", "error", "error_utils", + "event_engine_extensions", + "event_engine_query_extensions", "grpc_insecure_credentials", "handshaker_registry", "iomgr_fwd", diff --git a/src/core/ext/transport/binder/server/binder_server.cc b/src/core/ext/transport/binder/server/binder_server.cc index faf1641d7d1..6f4d932f436 100644 --- a/src/core/ext/transport/binder/server/binder_server.cc +++ b/src/core/ext/transport/binder/server/binder_server.cc @@ -160,7 +160,7 @@ class BinderServerListener : public Server::ListenerInterface { on_destroy_done_ = on_destroy_done; } - void Orphan() override { delete this; } + void Orphan() override { Unref(); } ~BinderServerListener() override { ExecCtx::Get()->Flush(); @@ -240,9 +240,8 @@ bool AddBinderPort(const std::string& addr, grpc_server* server, } std::string conn_id = addr.substr(kBinderUriScheme.size()); Server* core_server = Server::FromC(server); - core_server->AddListener( - OrphanablePtr(new BinderServerListener( - core_server, conn_id, std::move(factory), security_policy))); + core_server->AddListener(MakeOrphanable( + core_server, conn_id, std::move(factory), security_policy)); return true; } diff --git a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc index e00bcc1b379..7dd94de3090 100644 --- a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc +++ b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc @@ -103,8 +103,8 @@ absl::StatusOr ChaoticGoodServerListener::Bind( str.ok() ? str->c_str() : str.status().ToString().c_str()); } EventEngine::Listener::AcceptCallback accept_cb = - [self = Ref()](std::unique_ptr ep, - MemoryAllocator) { + [self = RefAsSubclass()]( + std::unique_ptr ep, MemoryAllocator) { ExecCtx exec_ctx; MutexLock lock(&self->mu_); if (self->shutdown_) return; @@ -149,7 +149,8 @@ absl::Status ChaoticGoodServerListener::StartListening() { ChaoticGoodServerListener::ActiveConnection::ActiveConnection( RefCountedPtr listener, std::unique_ptr endpoint) - : memory_allocator_(listener->memory_allocator_), listener_(listener) { + : memory_allocator_(listener->memory_allocator_), + listener_(std::move(listener)) { handshaking_state_ = MakeRefCounted(Ref()); handshaking_state_->Start(std::move(endpoint)); } diff --git a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h index 404bbbf946d..0479016c15b 100644 --- a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h +++ b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h @@ -49,9 +49,7 @@ namespace grpc_core { namespace chaotic_good { -class ChaoticGoodServerListener final - : public Server::ListenerInterface, - public RefCounted { +class ChaoticGoodServerListener final : public Server::ListenerInterface { public: static absl::AnyInvocable DefaultConnectionIDGenerator() { return [bitgen = absl::BitGen()]() mutable { diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 9b7770e4930..1c2ab26dc24 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/event_engine/channel_args_endpoint_config.h" +#include "src/core/lib/event_engine/extensions/supports_fd.h" +#include "src/core/lib/event_engine/query_extensions.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -67,6 +70,7 @@ #include "src/core/lib/gprpp/unique_type_name.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/event_engine_shims/endpoint.h" #include "src/core/lib/iomgr/iomgr_fwd.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -93,9 +97,11 @@ #endif // GPR_SUPPORT_CHANNELS_FROM_FD namespace grpc_core { -namespace { -using ::grpc_event_engine::experimental::EventEngine; +using grpc_event_engine::experimental::ChannelArgsEndpointConfig; +using grpc_event_engine::experimental::EventEngine; +using grpc_event_engine::experimental::EventEngineSupportsFdExtension; +using grpc_event_engine::experimental::QueryExtension; const char kUnixUriPrefix[] = "unix:"; const char kUnixAbstractUriPrefix[] = "unix-abstract:"; @@ -112,14 +118,23 @@ class Chttp2ServerListener : public Server::ListenerInterface { Server* server, const char* name, const ChannelArgs& args, Chttp2ServerArgsModifier args_modifier); + static Chttp2ServerListener* CreateForPassiveListener( + Server* server, const ChannelArgs& args, + std::shared_ptr passive_listener); + // Do not instantiate directly. Use one of the factory methods above. Chttp2ServerListener(Server* server, const ChannelArgs& args, - Chttp2ServerArgsModifier args_modifier); + Chttp2ServerArgsModifier args_modifier, + grpc_server_config_fetcher* config_fetcher, + std::shared_ptr + passive_listener = nullptr); ~Chttp2ServerListener() override; void Start(Server* server, const std::vector* pollsets) override; + void AcceptConnectedEndpoint(std::unique_ptr endpoint); + channelz::ListenSocketNode* channelz_listen_socket_node() const override { return channelz_listen_socket_.get(); } @@ -129,6 +144,8 @@ class Chttp2ServerListener : public Server::ListenerInterface { void Orphan() override; private: + friend class experimental::PassiveListenerImpl; + class ConfigFetcherWatcher : public grpc_server_config_fetcher::WatcherInterface { public: @@ -235,34 +252,8 @@ class Chttp2ServerListener : public Server::ListenerInterface { static void DestroyListener(Server* /*server*/, void* arg, grpc_closure* destroy_done); - // The interface required by RefCountedPtr<> has been manually implemented - // here to take a ref on tcp_server_ instead. Note that, the handshaker - // needs tcp_server_ to exist for the lifetime of the handshake since it's - // needed by acceptor. Sharing refs between the listener and tcp_server_ is - // just an optimization to avoid taking additional refs on the listener, - // since TcpServerShutdownComplete already holds a ref to the listener. - void IncrementRefCount() { grpc_tcp_server_ref(tcp_server_); } - void IncrementRefCount(const DebugLocation& /* location */, - const char* /* reason */) { - IncrementRefCount(); - } - - GRPC_MUST_USE_RESULT RefCountedPtr Ref() { - IncrementRefCount(); - return RefCountedPtr(this); - } - GRPC_MUST_USE_RESULT RefCountedPtr Ref( - const DebugLocation& /* location */, const char* /* reason */) { - return Ref(); - } - - void Unref() { grpc_tcp_server_unref(tcp_server_); } - void Unref(const DebugLocation& /* location */, const char* /* reason */) { - Unref(); - } - - Server* const server_; - grpc_tcp_server* tcp_server_; + Server* const server_ = nullptr; + grpc_tcp_server* tcp_server_ = nullptr; grpc_resolved_address resolved_address_; Chttp2ServerArgsModifier const args_modifier_; ConfigFetcherWatcher* config_fetcher_watcher_ = nullptr; @@ -285,6 +276,10 @@ class Chttp2ServerListener : public Server::ListenerInterface { RefCountedPtr channelz_listen_socket_; MemoryQuotaRefPtr memory_quota_; ConnectionQuotaRefPtr connection_quota_; + grpc_server_config_fetcher* config_fetcher_ = nullptr; + // TODO(yashykt): consider using absl::variant<> to minimize memory usage for + // disjoint cases where different fields are used. + std::shared_ptr passive_listener_; }; // @@ -381,13 +376,17 @@ Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState( handshake_mgr_(MakeRefCounted()), deadline_(GetConnectionDeadline(args)), interested_parties_(grpc_pollset_set_create()) { - grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_); + if (accepting_pollset != nullptr) { + grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_); + } CoreConfiguration::Get().handshaker_registry().AddHandshakers( HANDSHAKER_SERVER, args, interested_parties_, handshake_mgr_.get()); } Chttp2ServerListener::ActiveConnection::HandshakingState::~HandshakingState() { - grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_); + if (accepting_pollset_ != nullptr) { + grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_); + } grpc_pollset_set_destroy(interested_parties_); gpr_free(acceptor_); } @@ -589,7 +588,11 @@ Chttp2ServerListener::ActiveConnection::ActiveConnection( grpc_schedule_on_exec_ctx); } -Chttp2ServerListener::ActiveConnection::~ActiveConnection() {} +Chttp2ServerListener::ActiveConnection::~ActiveConnection() { + if (listener_ != nullptr && listener_->tcp_server_ != nullptr) { + grpc_tcp_server_unref(listener_->tcp_server_); + } +} void Chttp2ServerListener::ActiveConnection::Orphan() { OrphanablePtr handshaking_state; @@ -637,6 +640,9 @@ void Chttp2ServerListener::ActiveConnection::Start( const ChannelArgs& args) { RefCountedPtr handshaking_state_ref; listener_ = std::move(listener); + if (listener_->tcp_server_ != nullptr) { + grpc_tcp_server_ref(listener_->tcp_server_); + } { ReleasableMutexLock lock(&mu_); if (shutdown_) { @@ -709,83 +715,82 @@ void Chttp2ServerListener::ActiveConnection::OnDrainGraceTimeExpiry() { grpc_error_handle Chttp2ServerListener::Create( Server* server, grpc_resolved_address* addr, const ChannelArgs& args, Chttp2ServerArgsModifier args_modifier, int* port_num) { - Chttp2ServerListener* listener = nullptr; - // The bulk of this method is inside of a lambda to make cleanup - // easier without using goto. - grpc_error_handle error = [&]() { - grpc_error_handle error; - // Create Chttp2ServerListener. - listener = new Chttp2ServerListener(server, args, args_modifier); - error = grpc_tcp_server_create( - &listener->tcp_server_shutdown_complete_, - grpc_event_engine::experimental::ChannelArgsEndpointConfig(args), - OnAccept, listener, &listener->tcp_server_); + // Create Chttp2ServerListener. + OrphanablePtr listener = + MakeOrphanable(server, args, args_modifier, + server->config_fetcher()); + // The tcp_server will be unreffed when the listener is orphaned, which could + // be at the end of this function if the listener was not added to the + // server's set of listeners. + grpc_error_handle error = grpc_tcp_server_create( + &listener->tcp_server_shutdown_complete_, ChannelArgsEndpointConfig(args), + OnAccept, listener.get(), &listener->tcp_server_); + if (!error.ok()) return error; + if (listener->config_fetcher_ != nullptr) { + listener->resolved_address_ = *addr; + // TODO(yashykt): Consider binding so as to be able to return the port + // number. + } else { + error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num); if (!error.ok()) return error; - if (server->config_fetcher() != nullptr) { - listener->resolved_address_ = *addr; - // TODO(yashykt): Consider binding so as to be able to return the port - // number. - } else { - error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num); - if (!error.ok()) return error; - } - // Create channelz node. - if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ) - .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) { - auto string_address = grpc_sockaddr_to_uri(addr); - if (!string_address.ok()) { - return GRPC_ERROR_CREATE(string_address.status().ToString()); - } - listener->channelz_listen_socket_ = - MakeRefCounted( - *string_address, - absl::StrCat("chttp2 listener ", *string_address)); - } - // Register with the server only upon success - server->AddListener(OrphanablePtr(listener)); - return absl::OkStatus(); - }(); - if (!error.ok()) { - if (listener != nullptr) { - if (listener->tcp_server_ != nullptr) { - // listener is deleted when tcp_server_ is shutdown. - grpc_tcp_server_unref(listener->tcp_server_); - } else { - delete listener; - } + } + // Create channelz node. + if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ) + .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) { + auto string_address = grpc_sockaddr_to_uri(addr); + if (!string_address.ok()) { + return GRPC_ERROR_CREATE(string_address.status().ToString()); } + listener->channelz_listen_socket_ = + MakeRefCounted( + *string_address, absl::StrCat("chttp2 listener ", *string_address)); } - return error; + // Register with the server only upon success + server->AddListener(std::move(listener)); + return absl::OkStatus(); } grpc_error_handle Chttp2ServerListener::CreateWithAcceptor( Server* server, const char* name, const ChannelArgs& args, Chttp2ServerArgsModifier args_modifier) { - Chttp2ServerListener* listener = - new Chttp2ServerListener(server, args, args_modifier); + auto listener = MakeOrphanable( + server, args, args_modifier, server->config_fetcher()); grpc_error_handle error = grpc_tcp_server_create( - &listener->tcp_server_shutdown_complete_, - grpc_event_engine::experimental::ChannelArgsEndpointConfig(args), - OnAccept, listener, &listener->tcp_server_); - if (!error.ok()) { - delete listener; - return error; - } + &listener->tcp_server_shutdown_complete_, ChannelArgsEndpointConfig(args), + OnAccept, listener.get(), &listener->tcp_server_); + if (!error.ok()) return error; // TODO(yangg) channelz TcpServerFdHandler** arg_val = args.GetPointer(name); *arg_val = grpc_tcp_server_create_fd_handler(listener->tcp_server_); - server->AddListener(OrphanablePtr(listener)); + server->AddListener(std::move(listener)); return absl::OkStatus(); } +Chttp2ServerListener* Chttp2ServerListener::CreateForPassiveListener( + Server* server, const ChannelArgs& args, + std::shared_ptr passive_listener) { + // TODO(hork): figure out how to handle channelz in this case + auto listener = MakeOrphanable( + server, args, /*args_modifier=*/ + [](const ChannelArgs& args, grpc_error_handle*) { return args; }, nullptr, + std::move(passive_listener)); + auto listener_ptr = listener.get(); + server->AddListener(std::move(listener)); + return listener_ptr; +} + Chttp2ServerListener::Chttp2ServerListener( Server* server, const ChannelArgs& args, - Chttp2ServerArgsModifier args_modifier) + Chttp2ServerArgsModifier args_modifier, + grpc_server_config_fetcher* config_fetcher, + std::shared_ptr passive_listener) : server_(server), args_modifier_(args_modifier), args_(args), memory_quota_(args.GetObject()->memory_quota()), - connection_quota_(MakeRefCounted()) { + connection_quota_(MakeRefCounted()), + config_fetcher_(config_fetcher), + passive_listener_(std::move(passive_listener)) { auto max_allowed_incoming_connections = args.GetInt(GRPC_ARG_MAX_ALLOWED_INCOMING_CONNECTIONS); if (max_allowed_incoming_connections.has_value()) { @@ -800,6 +805,9 @@ Chttp2ServerListener::~Chttp2ServerListener() { // Flush queued work before destroying handshaker factory, since that // may do a synchronous unref. ExecCtx::Get()->Flush(); + if (passive_listener_ != nullptr) { + passive_listener_->ListenerDestroyed(); + } if (on_destroy_done_ != nullptr) { ExecCtx::Run(DEBUG_LOCATION, on_destroy_done_, absl::OkStatus()); ExecCtx::Get()->Flush(); @@ -809,10 +817,11 @@ Chttp2ServerListener::~Chttp2ServerListener() { // Server callback: start listening on our ports void Chttp2ServerListener::Start( Server* /*server*/, const std::vector* /* pollsets */) { - if (server_->config_fetcher() != nullptr) { - auto watcher = std::make_unique(Ref()); + if (config_fetcher_ != nullptr) { + auto watcher = std::make_unique( + RefAsSubclass()); config_fetcher_watcher_ = watcher.get(); - server_->config_fetcher()->StartWatch( + config_fetcher_->StartWatch( grpc_sockaddr_to_string(&resolved_address_, false).value(), std::move(watcher)); } else { @@ -826,7 +835,9 @@ void Chttp2ServerListener::Start( } void Chttp2ServerListener::StartListening() { - grpc_tcp_server_start(tcp_server_, &server_->pollsets()); + if (tcp_server_ != nullptr) { + grpc_tcp_server_start(tcp_server_, &server_->pollsets()); + } } void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) { @@ -834,6 +845,12 @@ void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) { on_destroy_done_ = on_destroy_done; } +void Chttp2ServerListener::AcceptConnectedEndpoint( + std::unique_ptr endpoint) { + OnAccept(this, grpc_event_engine_endpoint_create(std::move(endpoint)), + /*accepting_pollset=*/nullptr, /*acceptor=*/nullptr); +} + void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor) { @@ -858,7 +875,7 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, endpoint_cleanup(error); return; } - if (self->server_->config_fetcher() != nullptr) { + if (self->config_fetcher_ != nullptr) { if (connection_manager == nullptr) { grpc_error_handle error = GRPC_ERROR_CREATE( "No ConnectionManager configured. Closing connection."); @@ -899,7 +916,7 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, // heap-use-after-free issues where `Ref()` is invoked when the ref of // tcp_server_ has already reached 0. (Ref() implementation of // Chttp2ServerListener is grpc_tcp_server_ref().) - listener_ref = self->Ref(); + listener_ref = self->RefAsSubclass(); self->connections_.emplace(connection.get(), std::move(connection)); } } @@ -914,7 +931,7 @@ void Chttp2ServerListener::TcpServerShutdownComplete( void* arg, grpc_error_handle /*error*/) { Chttp2ServerListener* self = static_cast(arg); self->channelz_listen_socket_.reset(); - delete self; + self->Unref(); } // Server callback: destroy the tcp listener (so we don't generate further @@ -923,7 +940,8 @@ void Chttp2ServerListener::Orphan() { // Cancel the watch before shutting down so as to avoid holding a ref to the // listener in the watcher. if (config_fetcher_watcher_ != nullptr) { - server_->config_fetcher()->CancelWatch(config_fetcher_watcher_); + CHECK_NE(config_fetcher_, nullptr); + config_fetcher_->CancelWatch(config_fetcher_watcher_); } std::map> connections; grpc_tcp_server* tcp_server; @@ -941,12 +959,14 @@ void Chttp2ServerListener::Orphan() { } tcp_server = tcp_server_; } - grpc_tcp_server_shutdown_listeners(tcp_server); - grpc_tcp_server_unref(tcp_server); + if (tcp_server != nullptr) { + grpc_tcp_server_shutdown_listeners(tcp_server); + grpc_tcp_server_unref(tcp_server); + } else { + Unref(); + } } -} // namespace - // // Chttp2ServerAddPort() // @@ -1047,6 +1067,50 @@ ChannelArgs ModifyArgsForConnection(const ChannelArgs& args, } } // namespace + +namespace experimental { + +absl::Status PassiveListenerImpl::AcceptConnectedEndpoint( + std::unique_ptr endpoint) { + CHECK_NE(server_.get(), nullptr); + RefCountedPtr listener; + { + MutexLock lock(&mu_); + if (listener_ != nullptr) { + listener = + listener_->RefIfNonZero().TakeAsSubclass(); + } + } + if (listener == nullptr) { + return absl::UnavailableError("passive listener already shut down"); + } + ExecCtx exec_ctx; + listener->AcceptConnectedEndpoint(std::move(endpoint)); + return absl::OkStatus(); +} + +absl::Status PassiveListenerImpl::AcceptConnectedFd(int fd) { + CHECK_NE(server_.get(), nullptr); + ExecCtx exec_ctx; + auto& args = server_->channel_args(); + auto* supports_fd = QueryExtension( + /*engine=*/args.GetObjectRef().get()); + if (supports_fd == nullptr) { + return absl::UnimplementedError( + "The server's EventEngine does not support adding endpoints from " + "connected file descriptors."); + } + auto endpoint = + supports_fd->CreateEndpointFromFd(fd, ChannelArgsEndpointConfig(args)); + return AcceptConnectedEndpoint(std::move(endpoint)); +} + +void PassiveListenerImpl::ListenerDestroyed() { + MutexLock lock(&mu_); + listener_ = nullptr; +} + +} // namespace experimental } // namespace grpc_core int grpc_server_add_http2_port(grpc_server* server, const char* addr, @@ -1144,3 +1208,31 @@ void grpc_server_add_channel_from_fd(grpc_server* /* server */, int /* fd */, } #endif // GPR_SUPPORT_CHANNELS_FROM_FD + +absl::Status grpc_server_add_passive_listener( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener) { + grpc_core::ExecCtx exec_ctx; + GRPC_API_TRACE("grpc_server_add_passive_listener(server=%p, credentials=%p)", + 2, (server, credentials)); + // Create security context. + if (credentials == nullptr) { + return absl::UnavailableError( + "No credentials specified for passive listener"); + } + auto sc = credentials->create_security_connector(grpc_core::ChannelArgs()); + if (sc == nullptr) { + return absl::UnavailableError( + absl::StrCat("Unable to create secure server with credentials of type ", + credentials->type().name())); + } + auto args = server->channel_args() + .SetObject(credentials->Ref()) + .SetObject(std::move(sc)); + passive_listener->listener_ = + grpc_core::Chttp2ServerListener::CreateForPassiveListener( + server, args, passive_listener); + passive_listener->server_ = server->Ref(); + return absl::OkStatus(); +} diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h index 26c178be917..25d38236aed 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.h +++ b/src/core/ext/transport/chttp2/server/chttp2_server.h @@ -21,6 +21,7 @@ #include +#include #include #include "src/core/lib/channel/channel_args.h" @@ -42,6 +43,38 @@ grpc_error_handle Chttp2ServerAddPort( Server* server, const char* addr, const ChannelArgs& args, Chttp2ServerArgsModifier connection_args_modifier, int* port_num); +class Chttp2ServerListener; +namespace experimental { + +// An implementation of the public C++ passive listener interface. +// The server builder holds a weak_ptr to one of these objects, and the +// application owns the instance. +class PassiveListenerImpl final : public PassiveListener { + public: + absl::Status AcceptConnectedEndpoint( + std::unique_ptr + endpoint) override ABSL_LOCKS_EXCLUDED(mu_); + + absl::Status AcceptConnectedFd(GRPC_UNUSED int fd) override + ABSL_LOCKS_EXCLUDED(mu_); + + void ListenerDestroyed() ABSL_LOCKS_EXCLUDED(mu_); + + private: + // note: the grpc_core::Server redundant namespace qualification is + // required for older gcc versions. + friend absl::Status(::grpc_server_add_passive_listener)( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener); + + Mutex mu_; + // Data members will be populated when initialized. + RefCountedPtr server_; + Chttp2ServerListener* listener_; +}; + +} // namespace experimental } // namespace grpc_core #endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H diff --git a/src/core/lib/event_engine/extensions/supports_fd.h b/src/core/lib/event_engine/extensions/supports_fd.h index 66ea1c2b345..30f0d2ad0e6 100644 --- a/src/core/lib/event_engine/extensions/supports_fd.h +++ b/src/core/lib/event_engine/extensions/supports_fd.h @@ -112,6 +112,13 @@ class EventEngineSupportsFdExtension { int fd, const EndpointConfig& config, MemoryAllocator memory_allocator) = 0; + /// Creates an EventEngine::Endpoint from an fd which is already assumed to be + /// connected to a remote peer. See \a CreatePosixEndpointFromFd for details. + /// This has the same behavior, but the \a memory_allocator is taken from the + /// EndpointConfig's resource quota. + virtual std::unique_ptr CreateEndpointFromFd( + int fd, const EndpointConfig& config) = 0; + /// Called when the posix listener has accepted a new client connection. /// \a listener_fd - The listening socket fd that accepted the new client /// connection. diff --git a/src/core/lib/event_engine/posix_engine/posix_engine.cc b/src/core/lib/event_engine/posix_engine/posix_engine.cc index e96c969617c..e4d5deb73dc 100644 --- a/src/core/lib/event_engine/posix_engine/posix_engine.cc +++ b/src/core/lib/event_engine/posix_engine/posix_engine.cc @@ -677,6 +677,22 @@ PosixEventEngine::CreatePosixEndpointFromFd(int fd, #endif // GRPC_PLATFORM_SUPPORTS_POSIX_POLLING } +std::unique_ptr PosixEventEngine::CreateEndpointFromFd( + int fd, const EndpointConfig& config) { + auto options = TcpOptionsFromEndpointConfig(config); + MemoryAllocator allocator; + if (options.memory_allocator_factory != nullptr) { + return CreatePosixEndpointFromFd( + fd, config, + options.memory_allocator_factory->CreateMemoryAllocator( + absl::StrCat("allocator:", fd))); + } + return CreatePosixEndpointFromFd( + fd, config, + options.resource_quota->memory_quota()->CreateMemoryAllocator( + absl::StrCat("allocator:", fd))); +} + absl::StatusOr> PosixEventEngine::CreateListener( Listener::AcceptCallback on_accept, diff --git a/src/core/lib/event_engine/posix_engine/posix_engine.h b/src/core/lib/event_engine/posix_engine/posix_engine.h index 257cd6b34b5..ea426c379c9 100644 --- a/src/core/lib/event_engine/posix_engine/posix_engine.h +++ b/src/core/lib/event_engine/posix_engine/posix_engine.h @@ -172,6 +172,8 @@ class PosixEventEngine final : public PosixEventEngineWithFdSupport, std::unique_ptr CreatePosixEndpointFromFd( int fd, const EndpointConfig& config, MemoryAllocator memory_allocator) override; + std::unique_ptr CreateEndpointFromFd( + int fd, const EndpointConfig& config) override; absl::StatusOr> CreateListener( Listener::AcceptCallback on_accept, diff --git a/src/core/server/server.h b/src/core/server/server.h index 486892b14d8..a4353794a37 100644 --- a/src/core/server/server.h +++ b/src/core/server/server.h @@ -39,6 +39,7 @@ #include "absl/types/optional.h" #include +#include #include #include #include @@ -74,6 +75,9 @@ "grpc.server.max_pending_requests_hard_limit" namespace grpc_core { +namespace experimental { +class PassiveListenerImpl; +} // namespace experimental extern TraceFlag grpc_server_channel_trace; @@ -112,7 +116,7 @@ class Server : public ServerInterface, /// Interface for listeners. /// Implementations must override the Orphan() method, which should stop /// listening and initiate destruction of the listener. - class ListenerInterface : public Orphanable { + class ListenerInterface : public InternallyRefCounted { public: ~ListenerInterface() override = default; @@ -212,6 +216,14 @@ class Server : public ServerInterface, void SendGoaways() ABSL_LOCKS_EXCLUDED(mu_global_, mu_call_); private: + // note: the grpc_core::Server redundant namespace qualification is + // required for older gcc versions. + // TODO(yashykt): eliminate this friend statement as part of your upcoming + // server listener refactoring. + friend absl::Status(::grpc_server_add_passive_listener)( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener); struct RequestedCall; class RequestMatcherInterface; diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index f989703fe1a..b9f71915981 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -47,11 +48,38 @@ #include #include +#include "src/core/ext/transport/chttp2/server/chttp2_server.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/server/server.h" #include "src/cpp/server/external_connection_acceptor_impl.h" namespace grpc { +namespace { + +// A PIMPL wrapper class that owns the only ref to the passive listener +// implementation. This is returned to the application. +class PassiveListenerOwner final + : public grpc_core::experimental::PassiveListener { + public: + explicit PassiveListenerOwner(std::shared_ptr listener) + : listener_(std::move(listener)) {} + + absl::Status AcceptConnectedEndpoint( + std::unique_ptr + endpoint) override { + return listener_->AcceptConnectedEndpoint(std::move(endpoint)); + } + + absl::Status AcceptConnectedFd(int fd) override { + return listener_->AcceptConnectedFd(fd); + } + + private: + std::shared_ptr listener_; +}; + +} // namespace static std::vector (*)()>* g_plugin_factory_list; @@ -225,6 +253,18 @@ ServerBuilder& ServerBuilder::SetResourceQuota( return *this; } +ServerBuilder& ServerBuilder::experimental_type::AddPassiveListener( + std::shared_ptr creds, + std::unique_ptr& passive_listener) { + auto core_passive_listener = + std::make_shared(); + builder_->unstarted_passive_listeners_.emplace_back(core_passive_listener, + std::move(creds)); + passive_listener = + std::make_unique(std::move(core_passive_listener)); + return *builder_; +} + ServerBuilder& ServerBuilder::AddListeningPort( const std::string& addr_uri, std::shared_ptr creds, int* selected_port) { @@ -398,6 +438,26 @@ std::unique_ptr ServerBuilder::BuildAndStart() { cq->RegisterServer(server.get()); } + for (auto& unstarted_listener : unstarted_passive_listeners_) { + has_frequently_polled_cqs = true; + auto passive_listener = unstarted_listener.passive_listener.lock(); + auto* core_server = grpc_core::Server::FromC(server->c_server()); + if (passive_listener != nullptr) { + auto* creds = unstarted_listener.credentials->c_creds(); + if (creds == nullptr) { + gpr_log(GPR_ERROR, "Credentials missing for PassiveListener"); + return nullptr; + } + auto success = grpc_server_add_passive_listener( + core_server, creds, std::move(passive_listener)); + if (!success.ok()) { + gpr_log(GPR_ERROR, "Failed to create a passive listener: %s", + success.ToString().c_str()); + return nullptr; + } + } + } + if (!has_frequently_polled_cqs) { gpr_log(GPR_ERROR, "At least one of the completion queues must be frequently polled"); diff --git a/test/core/event_engine/event_engine_test_utils.h b/test/core/event_engine/event_engine_test_utils.h index 67bbe42d35d..debef7a0449 100644 --- a/test/core/event_engine/event_engine_test_utils.h +++ b/test/core/event_engine/event_engine_test_utils.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -159,6 +160,70 @@ class NotifyOnDelete { grpc_core::Notification* signal_; }; +// An endpoint implementation that supports Read and Write via std::threads. +// Passing a grpc_core::Notification will allow owners to know when all +// in-flight callbacks have been run, and all endpoint state has been destroyed. +class ThreadedNoopEndpoint : public EventEngine::Endpoint { + public: + explicit ThreadedNoopEndpoint(grpc_core::Notification* destroyed) + : state_(std::make_shared(destroyed)) {} + ~ThreadedNoopEndpoint() override { + std::thread deleter([state = state_]() { + CleanupThread(state->read); + CleanupThread(state->write); + }); + deleter.detach(); + } + + bool Read(absl::AnyInvocable on_read, SliceBuffer* buffer, + const ReadArgs* /* args */) override { + buffer->Clear(); + CleanupThread(state_->read); + state_->read = new std::thread([cb = std::move(on_read)]() mutable { + cb(absl::UnknownError("test")); + }); + return false; + } + + bool Write(absl::AnyInvocable on_writable, + SliceBuffer* data, const WriteArgs* /* args */) override { + data->Clear(); + CleanupThread(state_->write); + state_->write = new std::thread([cb = std::move(on_writable)]() mutable { + cb(absl::UnknownError("test")); + }); + return false; + } + + const EventEngine::ResolvedAddress& GetPeerAddress() const override { + return peer_; + } + + const EventEngine::ResolvedAddress& GetLocalAddress() const override { + return local_; + } + + private: + struct EndpointState { + explicit EndpointState(grpc_core::Notification* deleter) + : delete_notifier_(deleter) {} + std::thread* read = nullptr; + std::thread* write = nullptr; + NotifyOnDelete delete_notifier_; + }; + + static void CleanupThread(std::thread* thd) { + if (thd != nullptr) { + thd->join(); + delete thd; + } + } + + std::shared_ptr state_; + EventEngine::ResolvedAddress peer_; + EventEngine::ResolvedAddress local_; +}; + } // namespace experimental } // namespace grpc_event_engine diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index ba2f115ee7a..b65ec5c9e86 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -28,6 +28,7 @@ grpc_cc_test( deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", + "//test/core/event_engine:event_engine_test_utils", "//test/core/test_util:grpc_test_util_base", "//test/core/test_util:grpc_test_util_unsecure", ], diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc index 1765a1d59bf..089f7c38ecf 100644 --- a/test/cpp/server/server_builder_test.cc +++ b/test/cpp/server/server_builder_test.cc @@ -16,14 +16,19 @@ // // +#include + #include +#include #include #include #include #include +#include "src/core/lib/gprpp/notification.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/event_engine/event_engine_test_utils.h" #include "test/core/test_util/port.h" #include "test/core/test_util/test_config.h" @@ -83,6 +88,56 @@ TEST_F(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { nullptr); } +TEST_F(ServerBuilderTest, AddPassiveListener) { + std::unique_ptr passive_listener; + auto server = + ServerBuilder() + .experimental() + .AddPassiveListener(InsecureServerCredentials(), passive_listener) + .BuildAndStart(); + server->Shutdown(); +} + +TEST_F(ServerBuilderTest, PassiveListenerAcceptConnectedFd) { + std::unique_ptr passive_listener; + ServerBuilder builder; + auto cq = builder.AddCompletionQueue(); + // TODO(hork): why is the service necessary? Queue isn't drained otherwise. + auto server = + builder.RegisterService(&g_service) + .experimental() + .AddPassiveListener(InsecureServerCredentials(), passive_listener) + .BuildAndStart(); + ASSERT_NE(server.get(), nullptr); +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + int fd = socket(AF_INET, SOCK_STREAM, 0); + auto accept_status = passive_listener->AcceptConnectedFd(fd); + ASSERT_TRUE(accept_status.ok()) << accept_status; +#else + int fd = -1; + auto accept_status = passive_listener->AcceptConnectedFd(fd); + ASSERT_FALSE(accept_status.ok()) << accept_status; +#endif + server->Shutdown(); +} + +TEST_F(ServerBuilderTest, PassiveListenerAcceptConnectedEndpoint) { + std::unique_ptr passive_listener; + auto server = + ServerBuilder() + .experimental() + .AddPassiveListener(InsecureServerCredentials(), passive_listener) + .BuildAndStart(); + grpc_core::Notification endpoint_destroyed; + auto success = passive_listener->AcceptConnectedEndpoint( + std::make_unique( + &endpoint_destroyed)); + ASSERT_TRUE(success.ok()) + << "AcceptConnectedEndpoint failure: " << success.ToString(); + endpoint_destroyed.WaitForNotification(); + server->Shutdown(); +} + } // namespace } // namespace grpc diff --git a/tools/distrib/check_namespace_qualification.py b/tools/distrib/check_namespace_qualification.py index 6634d8b8830..51ccb71aeb8 100755 --- a/tools/distrib/check_namespace_qualification.py +++ b/tools/distrib/check_namespace_qualification.py @@ -77,6 +77,10 @@ IGNORED_FILES = [ "src/core/lib/gprpp/global_config_env.h", "src/core/lib/profiling/timers.h", "src/core/lib/gprpp/crash.h", + # The grpc_core::Server redundant namespace qualification is required for + # older gcc versions. + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/server/server.h", ] # find our home diff --git a/tools/distrib/check_redundant_namespace_qualifiers.py b/tools/distrib/check_redundant_namespace_qualifiers.py index 0322332209b..72a5d8b7a3c 100755 --- a/tools/distrib/check_redundant_namespace_qualifiers.py +++ b/tools/distrib/check_redundant_namespace_qualifiers.py @@ -21,6 +21,13 @@ import os import re import sys +IGNORED_FILES = [ + # note: the grpc_core::Server redundant namespace qualification is required + # for older gcc versions. + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/server/server.h", +] + def find_closing_mustache(contents, initial_depth): """Find the closing mustache for a given number of open mustaches.""" @@ -166,6 +173,8 @@ for config in _CONFIGURATION: for file in files: if file.endswith(".cc") or file.endswith(".h"): path = os.path.join(root, file) + if path in IGNORED_FILES: + continue try: with open(path) as f: contents = f.read() diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 6a50207e16d..299c480565d 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -928,6 +928,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ @@ -1040,6 +1041,7 @@ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/impl/status.h \ include/grpcpp/impl/sync.h \ +include/grpcpp/passive_listener.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/audit_logging.h \ include/grpcpp/security/auth_context.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8dd3bb12622..02efb7460b9 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -928,6 +928,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ @@ -1040,6 +1041,7 @@ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/impl/status.h \ include/grpcpp/impl/sync.h \ +include/grpcpp/passive_listener.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/audit_logging.h \ include/grpcpp/security/auth_context.h \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 592e357f54f..20b553dadfe 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -861,6 +861,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 74fd1131517..f98a7a95a21 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -861,6 +861,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ From bc4766381ae2331c24b0eaa8fb24894d8c5c7289 Mon Sep 17 00:00:00 2001 From: Yijie Ma Date: Thu, 9 May 2024 14:28:51 -0700 Subject: [PATCH 15/33] [metrics] Templatized Metrics API (#36449) This adds compile-time checking that the type of the value and the size of the labels and optional labels passed when recording a metric must match with the type and the size specified when the metric is registered. The RegistrationBuilder API idea is credited to @ctiller. Closes #36449 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36449 from yijiem:registration-builder-api a72781013699a985a8e06152594268d6c45a9589 PiperOrigin-RevId: 632271022 --- src/core/lib/channel/metrics.cc | 193 +------ src/core/lib/channel/metrics.h | 308 +++++++--- .../load_balancing/pick_first/pick_first.cc | 12 +- src/core/load_balancing/rls/rls.cc | 49 +- .../weighted_round_robin.cc | 31 +- src/core/xds/grpc/xds_client_grpc.cc | 34 +- src/cpp/ext/otel/otel_plugin.cc | 251 ++++---- src/cpp/ext/otel/otel_plugin.h | 20 +- test/core/channel/metrics_test.cc | 534 +++++++++--------- test/core/load_balancing/pick_first_test.cc | 13 +- .../weighted_round_robin_test.cc | 23 +- test/core/test_util/fake_stats_plugin.cc | 52 +- test/core/test_util/fake_stats_plugin.h | 84 +-- test/cpp/end2end/rls_end2end_test.cc | 32 +- test/cpp/end2end/xds/xds_core_end2end_test.cc | 48 +- test/cpp/end2end/xds/xds_wrr_end2end_test.cc | 8 +- test/cpp/ext/otel/otel_plugin_test.cc | 116 ++-- 17 files changed, 945 insertions(+), 863 deletions(-) diff --git a/src/core/lib/channel/metrics.cc b/src/core/lib/channel/metrics.cc index d662f3275ad..c3b734fc44d 100644 --- a/src/core/lib/channel/metrics.cc +++ b/src/core/lib/channel/metrics.cc @@ -34,12 +34,14 @@ GlobalInstrumentsRegistry::GetInstrumentList() { return *instruments; } -GlobalInstrumentsRegistry::GlobalUInt64CounterHandle -GlobalInstrumentsRegistry::RegisterUInt64Counter( +GlobalInstrumentsRegistry::InstrumentID +GlobalInstrumentsRegistry::RegisterInstrument( + GlobalInstrumentsRegistry::ValueType value_type, + GlobalInstrumentsRegistry::InstrumentType instrument_type, absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { + absl::string_view unit, bool enable_by_default, + absl::Span label_keys, + absl::Span optional_label_keys) { auto& instruments = GetInstrumentList(); for (const auto& descriptor : instruments) { if (descriptor.name == name) { @@ -47,11 +49,11 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter( absl::StrFormat("Metric name %s has already been registered.", name)); } } - uint32_t index = instruments.size(); + InstrumentID index = instruments.size(); CHECK_LT(index, std::numeric_limits::max()); GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kUInt64; - descriptor.instrument_type = InstrumentType::kCounter; + descriptor.value_type = value_type; + descriptor.instrument_type = instrument_type; descriptor.index = index; descriptor.enable_by_default = enable_by_default; descriptor.name = name; @@ -61,169 +63,7 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter( descriptor.optional_label_keys = {optional_label_keys.begin(), optional_label_keys.end()}; instruments.push_back(std::move(descriptor)); - GlobalUInt64CounterHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalDoubleCounterHandle -GlobalInstrumentsRegistry::RegisterDoubleCounter( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kDouble; - descriptor.instrument_type = InstrumentType::kCounter; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalDoubleCounterHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle -GlobalInstrumentsRegistry::RegisterUInt64Histogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kUInt64; - descriptor.instrument_type = InstrumentType::kHistogram; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalUInt64HistogramHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle -GlobalInstrumentsRegistry::RegisterDoubleHistogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kDouble; - descriptor.instrument_type = InstrumentType::kHistogram; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalDoubleHistogramHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle -GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kInt64; - descriptor.instrument_type = InstrumentType::kCallbackGauge; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalCallbackInt64GaugeHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle -GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kDouble; - descriptor.instrument_type = InstrumentType::kCallbackGauge; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalCallbackDoubleGaugeHandle handle; - handle.index = index; - return handle; + return index; } void GlobalInstrumentsRegistry::ForEach( @@ -242,7 +82,7 @@ GlobalInstrumentsRegistry::GetInstrumentDescriptor( RegisteredMetricCallback::RegisteredMetricCallback( GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group, absl::AnyInvocable callback, - std::vector metrics, + std::vector metrics, Duration min_interval) : stats_plugin_group_(stats_plugin_group), callback_(std::move(callback)), @@ -259,15 +99,6 @@ RegisteredMetricCallback::~RegisteredMetricCallback() { } } -std::unique_ptr -GlobalStatsPluginRegistry::StatsPluginGroup::RegisterCallback( - absl::AnyInvocable callback, - std::vector metrics, - Duration min_interval) { - return std::make_unique( - *this, std::move(callback), std::move(metrics), min_interval); -} - void GlobalStatsPluginRegistry::StatsPluginGroup::AddClientCallTracers( const Slice& path, bool registered_method, grpc_call_context_element* call_context) { diff --git a/src/core/lib/channel/metrics.h b/src/core/lib/channel/metrics.h index 7c161c80829..797be93fd7d 100644 --- a/src/core/lib/channel/metrics.h +++ b/src/core/lib/channel/metrics.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "absl/functional/any_invocable.h" @@ -45,6 +46,27 @@ constexpr absl::string_view kMetricLabelTarget = "grpc.target"; // startup, before the execution of the main function (during dynamic // initialization time). Using this API after the main function begins may // result into missing instruments. This API is thread-unsafe. +// +// The registration of instruments is done through the templated +// RegistrationBuilder API and gets back a handle with an opaque type. At +// runtime, the handle should be used with the StatsPluginGroup API to record +// metrics for the instruments. +// +// At dynamic initialization time: +// const auto kMetricHandle = +// GlobalInstrumentsRegistry::RegisterUInt64Counter( +// "name", +// "description", +// "unit", /*enable_by_default=*/false) +// .Labels(kLabel1, kLabel2, kLabel3) +// .OptionalLabels(kOptionalLabel1, kOptionalLabel2) +// .Build(); +// +// At runtime time: +// stats_plugin_group.AddCounter(kMetricHandle, 1, +// {"label_value_1", "label_value_2", "label_value_3"}, +// {"optional_label_value_1", "optional_label_value_2"}); +// class GlobalInstrumentsRegistry { public: enum class ValueType { @@ -78,46 +100,113 @@ class GlobalInstrumentsRegistry { // runs or between different versions. InstrumentID index; }; - struct GlobalUInt64CounterHandle : public GlobalInstrumentHandle {}; - struct GlobalDoubleCounterHandle : public GlobalInstrumentHandle {}; - struct GlobalUInt64HistogramHandle : public GlobalInstrumentHandle {}; - struct GlobalDoubleHistogramHandle : public GlobalInstrumentHandle {}; - struct GlobalCallbackInt64GaugeHandle : public GlobalInstrumentHandle {}; - struct GlobalCallbackDoubleGaugeHandle : public GlobalInstrumentHandle {}; - using GlobalCallbackHandle = absl::variant; + + template + struct TypedGlobalInstrumentHandle : public GlobalInstrumentHandle {}; + + template + class RegistrationBuilder { + public: + template + RegistrationBuilder Labels(Args&&... args) { + return RegistrationBuilder( + name_, description_, unit_, enable_by_default_, + std::array({args...}), + optional_label_keys_); + } + + template + RegistrationBuilder OptionalLabels( + Args&&... args) { + return RegistrationBuilder( + name_, description_, unit_, enable_by_default_, label_keys_, + std::array({args...})); + } + + TypedGlobalInstrumentHandle Build() { + TypedGlobalInstrumentHandle handle; + handle.index = RegisterInstrument(V, I, name_, description_, unit_, + enable_by_default_, label_keys_, + optional_label_keys_); + return handle; + } + + private: + friend class GlobalInstrumentsRegistry; + + RegistrationBuilder(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) + : name_(name), + description_(description), + unit_(unit), + enable_by_default_(enable_by_default) {} + + RegistrationBuilder(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default, + std::array label_keys, + std::array optional_label_keys) + : name_(name), + description_(description), + unit_(unit), + enable_by_default_(enable_by_default), + label_keys_(std::move(label_keys)), + optional_label_keys_(std::move(optional_label_keys)) {} + + absl::string_view name_; + absl::string_view description_; + absl::string_view unit_; + bool enable_by_default_; + std::array label_keys_; + std::array optional_label_keys_; + }; // Creates instrument in the GlobalInstrumentsRegistry. - static GlobalUInt64CounterHandle RegisterUInt64Counter( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalDoubleCounterHandle RegisterDoubleCounter( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalUInt64HistogramHandle RegisterUInt64Histogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalDoubleHistogramHandle RegisterDoubleHistogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalCallbackInt64GaugeHandle RegisterCallbackInt64Gauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalCallbackDoubleGaugeHandle RegisterCallbackDoubleGauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); + static RegistrationBuilder + RegisterUInt64Counter(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, enable_by_default); + } + static RegistrationBuilder + RegisterDoubleCounter(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, enable_by_default); + } + static RegistrationBuilder + RegisterUInt64Histogram(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, + enable_by_default); + } + static RegistrationBuilder + RegisterDoubleHistogram(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, + enable_by_default); + } + static RegistrationBuilder + RegisterCallbackInt64Gauge(absl::string_view name, + absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder( + name, description, unit, enable_by_default); + } + static RegistrationBuilder + RegisterCallbackDoubleGauge(absl::string_view name, + absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder( + name, description, unit, enable_by_default); + } static void ForEach( absl::FunctionRef f); @@ -131,6 +220,12 @@ class GlobalInstrumentsRegistry { static std::vector& GetInstrumentList(); + static InstrumentID RegisterInstrument( + ValueType value_type, InstrumentType instrument_type, + absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default, + absl::Span label_keys, + absl::Span optional_label_keys); }; // An interface for implementing callback-style metrics. @@ -139,13 +234,35 @@ class CallbackMetricReporter { public: virtual ~CallbackMetricReporter() = default; - virtual void Report( - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, - int64_t value, absl::Span label_values, + template + void Report( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kInt64, + GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N> + handle, + int64_t value, std::array label_values, + std::array optional_values) { + ReportInt64(handle, value, label_values, optional_values); + } + template + void Report( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N> + handle, + double value, std::array label_values, + std::array optional_values) { + ReportDouble(handle, value, label_values, optional_values); + } + + private: + virtual void ReportInt64( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, + absl::Span label_values, absl::Span optional_values) = 0; - virtual void Report( - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle, - double value, absl::Span label_values, + virtual void ReportDouble( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_values) = 0; }; @@ -179,15 +296,15 @@ class StatsPlugin { // this measurement and must match with their corresponding keys in // GlobalInstrumentsRegistry::RegisterUInt64Counter(). virtual void AddCounter( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_label_values) = 0; // Adds \a value to the double counter specified by \a handle. \a label_values // and \a optional_label_values specify attributes that are associated with // this measurement and must match with their corresponding keys in // GlobalInstrumentsRegistry::RegisterDoubleCounter(). virtual void AddCounter( - GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_label_values) = 0; // Records a uint64 \a value to the histogram specified by \a handle. \a @@ -195,16 +312,16 @@ class StatsPlugin { // associated with this measurement and must match with their corresponding // keys in GlobalInstrumentsRegistry::RegisterUInt64Histogram(). virtual void RecordHistogram( - GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_label_values) = 0; // Records a double \a value to the histogram specified by \a handle. \a // label_values and \a optional_label_values specify attributes that are // associated with this measurement and must match with their corresponding // keys in GlobalInstrumentsRegistry::RegisterDoubleHistogram(). virtual void RecordHistogram( - GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, - double value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_label_values) = 0; // Adds a callback to be invoked when the stats plugin wants to // populate the corresponding metrics (see callback->metrics() for list). @@ -255,20 +372,53 @@ class GlobalStatsPluginRegistry { } // Adds a counter in all stats plugins within the group. See the StatsPlugin // interface for more documentation and valid types. - template - void AddCounter(HandleType handle, ValueType value, - absl::Span label_values, - absl::Span optional_values) { + template + void AddCounter( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N> + handle, + uint64_t value, std::array label_values, + std::array optional_values) { + for (auto& state : plugins_state_) { + state.plugin->AddCounter(handle, value, label_values, optional_values); + } + } + template + void AddCounter( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N> + handle, + double value, std::array label_values, + std::array optional_values) { for (auto& state : plugins_state_) { state.plugin->AddCounter(handle, value, label_values, optional_values); } } // Records a value to a histogram in all stats plugins within the group. See // the StatsPlugin interface for more documentation and valid types. - template - void RecordHistogram(HandleType handle, ValueType value, - absl::Span label_values, - absl::Span optional_values) { + template + void RecordHistogram( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N> + handle, + uint64_t value, std::array label_values, + std::array optional_values) { + for (auto& state : plugins_state_) { + state.plugin->RecordHistogram(handle, value, label_values, + optional_values); + } + } + template + void RecordHistogram( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N> + handle, + double value, std::array label_values, + std::array optional_values) { for (auto& state : plugins_state_) { state.plugin->RecordHistogram(handle, value, label_values, optional_values); @@ -285,11 +435,17 @@ class GlobalStatsPluginRegistry { // the lifetime of the callback; when the returned object is // destroyed, the callback is de-registered. The returned object // must not outlive the StatsPluginGroup object that created it. + template GRPC_MUST_USE_RESULT std::unique_ptr - RegisterCallback( - absl::AnyInvocable callback, - std::vector metrics, - Duration min_interval = Duration::Seconds(5)); + RegisterCallback(absl::AnyInvocable callback, + Duration min_interval, Args... args) { + AssertIsCallbackGaugeHandle(args...); + return std::make_unique( + *this, std::move(callback), + std::vector{ + args...}, + min_interval); + } // Adds all available client call tracers associated with the stats plugins // within the group to \a call_context. @@ -307,6 +463,24 @@ class GlobalStatsPluginRegistry { std::shared_ptr plugin; }; + // C++17 has fold expression that may simplify this. + template + static constexpr void AssertIsCallbackGaugeHandle( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle) { + static_assert(V == GlobalInstrumentsRegistry::ValueType::kInt64 || + V == GlobalInstrumentsRegistry::ValueType::kDouble, + "ValueType must be kInt64 or kDouble"); + static_assert( + I == GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, + "InstrumentType must be kCallbackGauge"); + } + template + static constexpr void AssertIsCallbackGaugeHandle(T t, Args&&... args) { + AssertIsCallbackGaugeHandle(t); + AssertIsCallbackGaugeHandle(args...); + } + std::vector plugins_state_; }; @@ -335,7 +509,7 @@ class RegisteredMetricCallback { RegisteredMetricCallback( GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group, absl::AnyInvocable callback, - std::vector metrics, + std::vector metrics, Duration min_interval); ~RegisteredMetricCallback(); @@ -344,8 +518,8 @@ class RegisteredMetricCallback { void Run(CallbackMetricReporter& reporter) { callback_(reporter); } // Returns the set of metrics that this callback will modify. - const std::vector& metrics() - const { + const std::vector& + metrics() const { return metrics_; } @@ -356,7 +530,7 @@ class RegisteredMetricCallback { private: GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group_; absl::AnyInvocable callback_; - std::vector metrics_; + std::vector metrics_; Duration min_interval_; }; diff --git a/src/core/load_balancing/pick_first/pick_first.cc b/src/core/load_balancing/pick_first/pick_first.cc index afcd49d547d..2307128507e 100644 --- a/src/core/load_balancing/pick_first/pick_first.cc +++ b/src/core/load_balancing/pick_first/pick_first.cc @@ -84,19 +84,25 @@ const auto kMetricDisconnections = "grpc.lb.pick_first.disconnections", "EXPERIMENTAL. Number of times the selected subchannel becomes " "disconnected.", - "{disconnection}", {kMetricLabelTarget}, {}, false); + "{disconnection}", false) + .Labels(kMetricLabelTarget) + .Build(); const auto kMetricConnectionAttemptsSucceeded = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.pick_first.connection_attempts_succeeded", "EXPERIMENTAL. Number of successful connection attempts.", "{attempt}", - {kMetricLabelTarget}, {}, false); + false) + .Labels(kMetricLabelTarget) + .Build(); const auto kMetricConnectionAttemptsFailed = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.pick_first.connection_attempts_failed", "EXPERIMENTAL. Number of failed connection attempts.", "{attempt}", - {kMetricLabelTarget}, {}, false); + false) + .Labels(kMetricLabelTarget) + .Build(); class PickFirstConfig final : public LoadBalancingPolicy::Config { public: diff --git a/src/core/load_balancing/rls/rls.cc b/src/core/load_balancing/rls/rls.cc index 3e9f08a5b9c..53480d6f091 100644 --- a/src/core/load_balancing/rls/rls.cc +++ b/src/core/load_balancing/rls/rls.cc @@ -128,26 +128,27 @@ constexpr absl::string_view kMetricLabelPickResult = "grpc.lb.pick_result"; const auto kMetricCacheSize = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( "grpc.lb.rls.cache_size", "EXPERIMENTAL. Size of the RLS cache.", "By", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricLabelRlsInstanceUuid}, - {}, false); + false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricLabelRlsInstanceUuid) + .Build(); const auto kMetricCacheEntries = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( "grpc.lb.rls.cache_entries", - "EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricLabelRlsInstanceUuid}, - {}, false); + "EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricLabelRlsInstanceUuid) + .Build(); const auto kMetricDefaultTargetPicks = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.rls.default_target_picks", "EXPERIMENTAL. Number of LB picks sent to the default target.", - "{pick}", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricRlsDataPlaneTarget, kMetricLabelPickResult}, - {}, false); + "{pick}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricRlsDataPlaneTarget, kMetricLabelPickResult) + .Build(); const auto kMetricTargetPicks = GlobalInstrumentsRegistry::RegisterUInt64Counter( @@ -156,17 +157,19 @@ const auto kMetricTargetPicks = "if the default target is also returned by the RLS server, RPCs sent " "to that target from the cache will be counted in this metric, not " "in grpc.rls.default_target_picks.", - "{pick}", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricRlsDataPlaneTarget, kMetricLabelPickResult}, - {}, false); + "{pick}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricRlsDataPlaneTarget, kMetricLabelPickResult) + .Build(); const auto kMetricFailedPicks = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.rls.failed_picks", "EXPERIMENTAL. Number of LB picks failed due to either a failed RLS " "request or the RLS channel being throttled.", - "{pick}", {kMetricLabelTarget, kMetricLabelRlsServerTarget}, {}, false); + "{pick}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget) + .Build(); constexpr absl::string_view kRls = "rls_experimental"; const char kGrpc[] = "grpc"; @@ -754,9 +757,9 @@ class RlsLb final : public LoadBalancingPolicy { // Updates the picker in the work serializer. void UpdatePickerLocked() ABSL_LOCKS_EXCLUDED(&mu_); - void MaybeExportPickCount( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - absl::string_view target, const PickResult& pick_result); + template + void MaybeExportPickCount(HandleType handle, absl::string_view target, + const PickResult& pick_result); const std::string instance_uuid_; @@ -1961,7 +1964,7 @@ RlsLb::RlsLb(Args args) MutexLock lock(&mu_); cache_.ReportMetricsLocked(reporter); }, - {kMetricCacheSize, kMetricCacheEntries})) { + Duration::Seconds(5), kMetricCacheSize, kMetricCacheEntries)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_rls_trace)) { gpr_log(GPR_INFO, "[rlslb %p] policy created", this); } @@ -2230,9 +2233,9 @@ void RlsLb::UpdatePickerLocked() { MakeRefCounted(RefAsSubclass(DEBUG_LOCATION, "Picker"))); } -void RlsLb::MaybeExportPickCount( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - absl::string_view target, const PickResult& pick_result) { +template +void RlsLb::MaybeExportPickCount(HandleType handle, absl::string_view target, + const PickResult& pick_result) { absl::string_view pick_result_string = Match( pick_result.result, [](const LoadBalancingPolicy::PickResult::Complete&) { diff --git a/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc b/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc index bf174c55a56..d0a4165f393 100644 --- a/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +++ b/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc @@ -85,12 +85,16 @@ constexpr absl::string_view kWeightedRoundRobin = "weighted_round_robin"; constexpr absl::string_view kMetricLabelLocality = "grpc.lb.locality"; -const auto kMetricRrFallback = GlobalInstrumentsRegistry::RegisterUInt64Counter( - "grpc.lb.wrr.rr_fallback", - "EXPERIMENTAL. Number of scheduler updates in which there were not " - "enough endpoints with valid weight, which caused the WRR policy to " - "fall back to RR behavior.", - "{update}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); +const auto kMetricRrFallback = + GlobalInstrumentsRegistry::RegisterUInt64Counter( + "grpc.lb.wrr.rr_fallback", + "EXPERIMENTAL. Number of scheduler updates in which there were not " + "enough endpoints with valid weight, which caused the WRR policy to " + "fall back to RR behavior.", + "{update}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); const auto kMetricEndpointWeightNotYetUsable = GlobalInstrumentsRegistry::RegisterUInt64Counter( @@ -99,14 +103,20 @@ const auto kMetricEndpointWeightNotYetUsable = "don't yet have usable weight information (i.e., either the load " "report has not yet been received, or it is within the blackout " "period).", - "{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); + "{endpoint}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); const auto kMetricEndpointWeightStale = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.wrr.endpoint_weight_stale", "EXPERIMENTAL. Number of endpoints from each scheduler update whose " "latest weight is older than the expiration period.", - "{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); + "{endpoint}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); const auto kMetricEndpointWeights = GlobalInstrumentsRegistry::RegisterDoubleHistogram( @@ -115,7 +125,10 @@ const auto kMetricEndpointWeights = "Each bucket will be a counter that is incremented once for every " "endpoint whose weight is within that range. Note that endpoints " "without usable weights will have weight 0.", - "{weight}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); + "{weight}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); // Config for WRR policy. class WeightedRoundRobinConfig final : public LoadBalancingPolicy::Config { diff --git a/src/core/xds/grpc/xds_client_grpc.cc b/src/core/xds/grpc/xds_client_grpc.cc index 4408f96e2b6..7b7fee2ca76 100644 --- a/src/core/xds/grpc/xds_client_grpc.cc +++ b/src/core/xds/grpc/xds_client_grpc.cc @@ -99,20 +99,20 @@ const auto kMetricResourceUpdatesValid = "EXPERIMENTAL. A counter of resources received that were considered " "valid. The counter will be incremented even for resources that " "have not changed.", - "{resource}", - {kMetricLabelTarget, kMetricLabelXdsServer, - kMetricLabelXdsResourceType}, - {}, false); + "{resource}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer, + kMetricLabelXdsResourceType) + .Build(); const auto kMetricResourceUpdatesInvalid = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.xds_client.resource_updates_invalid", "EXPERIMENTAL. A counter of resources received that were considered " "invalid.", - "{resource}", - {kMetricLabelTarget, kMetricLabelXdsServer, - kMetricLabelXdsResourceType}, - {}, false); + "{resource}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer, + kMetricLabelXdsResourceType) + .Build(); const auto kMetricServerFailure = GlobalInstrumentsRegistry::RegisterUInt64Counter( @@ -121,7 +121,9 @@ const auto kMetricServerFailure = "unhealthy. A server goes unhealthy when we have a connectivity " "failure or when the ADS stream fails without seeing a response " "message, as per gRFC A57.", - "{failure}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false); + "{failure}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer) + .Build(); const auto kMetricConnected = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( @@ -132,15 +134,17 @@ const auto kMetricConnected = "ADS stream fails without seeing a response message, as per gRFC " "A57. It will be set to 1 when we receive the first response on " "an ADS stream.", - "{bool}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false); + "{bool}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer) + .Build(); const auto kMetricResources = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( "grpc.xds_client.resources", "EXPERIMENTAL. Number of xDS resources.", - "{resource}", - {kMetricLabelTarget, kMetricLabelXdsAuthority, - kMetricLabelXdsResourceType, kMetricLabelXdsCacheState}, - {}, false); + "{resource}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsAuthority, + kMetricLabelXdsResourceType, kMetricLabelXdsCacheState) + .Build(); } // namespace @@ -316,7 +320,7 @@ GrpcXdsClient::GrpcXdsClient( [this](CallbackMetricReporter& reporter) { ReportCallbackMetrics(reporter); }, - {kMetricConnected, kMetricResources})) {} + Duration::Seconds(5), kMetricConnected, kMetricResources)) {} void GrpcXdsClient::Orphaned() { registered_metric_callback_.reset(); diff --git a/src/cpp/ext/otel/otel_plugin.cc b/src/cpp/ext/otel/otel_plugin.cc index 18e0069a72a..acb81be35ee 100644 --- a/src/cpp/ext/otel/otel_plugin.cc +++ b/src/cpp/ext/otel/otel_plugin.cc @@ -249,27 +249,35 @@ OpenTelemetryPlugin::CallbackMetricReporter::CallbackMetricReporter( // that if a particular combination of labels was previously present but // is no longer present, we won't continue to report it. for (const auto& handle : key->metrics()) { - grpc_core::Match( - handle, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackInt64GaugeHandle& handle) { - auto& callback_gauge_state = - absl::get>>( - ot_plugin_->instruments_data_.at(handle.index).instrument); - callback_gauge_state->caches[key].clear(); - }, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackDoubleGaugeHandle& handle) { - auto& callback_gauge_state = - absl::get>>( - ot_plugin_->instruments_data_.at(handle.index).instrument); - callback_gauge_state->caches[key].clear(); - }); + const auto& descriptor = + grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle); + GPR_ASSERT( + descriptor.instrument_type == + grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); + switch (descriptor.value_type) { + case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: { + auto& callback_gauge_state = + absl::get>>( + ot_plugin_->instruments_data_.at(handle.index).instrument); + callback_gauge_state->caches[key].clear(); + break; + } + case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: { + auto& callback_gauge_state = + absl::get>>( + ot_plugin_->instruments_data_.at(handle.index).instrument); + callback_gauge_state->caches[key].clear(); + break; + } + default: + grpc_core::Crash(absl::StrFormat( + "Unknown or unsupported value type: %d", descriptor.value_type)); + } } } -void OpenTelemetryPlugin::CallbackMetricReporter::Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, +void OpenTelemetryPlugin::CallbackMetricReporter::ReportInt64( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index); @@ -296,9 +304,8 @@ void OpenTelemetryPlugin::CallbackMetricReporter::Report( cell.insert_or_assign(std::move(key), value); } -void OpenTelemetryPlugin::CallbackMetricReporter::Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle - handle, +void OpenTelemetryPlugin::CallbackMetricReporter::ReportDouble( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index); @@ -574,8 +581,8 @@ OpenTelemetryPlugin::IsEnabledForChannel( std::pair> OpenTelemetryPlugin::IsEnabledForServer( const grpc_core::ChannelArgs& args) const { - // Return true only if there is no server selector registered or if the server - // selector returns true. + // Return true only if there is no server selector registered or if the + // server selector returns true. if (server_selector_ == nullptr || server_selector_(args)) { return {true, std::make_shared(this, args)}; } @@ -583,7 +590,7 @@ OpenTelemetryPlugin::IsEnabledForServer( } void OpenTelemetryPlugin::AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -607,7 +614,7 @@ void OpenTelemetryPlugin::AddCounter( } void OpenTelemetryPlugin::AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -631,7 +638,7 @@ void OpenTelemetryPlugin::AddCounter( } void OpenTelemetryPlugin::RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -657,7 +664,7 @@ void OpenTelemetryPlugin::RecordHistogram( } void OpenTelemetryPlugin::RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -691,51 +698,59 @@ void OpenTelemetryPlugin::AddCallback( grpc_core::MutexLock lock(&mu_); callback_timestamps_.emplace(callback, grpc_core::Timestamp::InfPast()); for (const auto& handle : callback->metrics()) { - grpc_core::Match( - handle, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackInt64GaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - (*callback_gauge_state) - ->caches.emplace(callback, - CallbackGaugeState::Cache{}); - if (!std::exchange((*callback_gauge_state)->ot_callback_registered, - true)) { - gauges_that_need_to_add_callback.push_back( - callback_gauge_state->get()); - } - }, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackDoubleGaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - (*callback_gauge_state) - ->caches.emplace(callback, CallbackGaugeState::Cache{}); - if (!std::exchange((*callback_gauge_state)->ot_callback_registered, - true)) { - gauges_that_need_to_add_callback.push_back( - callback_gauge_state->get()); - } - }); + const auto& descriptor = + grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle); + GPR_ASSERT( + descriptor.instrument_type == + grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); + switch (descriptor.value_type) { + case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + (*callback_gauge_state) + ->caches.emplace(callback, CallbackGaugeState::Cache{}); + if (!std::exchange((*callback_gauge_state)->ot_callback_registered, + true)) { + gauges_that_need_to_add_callback.push_back( + callback_gauge_state->get()); + } + break; + } + case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + (*callback_gauge_state) + ->caches.emplace(callback, CallbackGaugeState::Cache{}); + if (!std::exchange((*callback_gauge_state)->ot_callback_registered, + true)) { + gauges_that_need_to_add_callback.push_back( + callback_gauge_state->get()); + } + break; + } + default: + grpc_core::Crash(absl::StrFormat( + "Unknown or unsupported value type: %d", descriptor.value_type)); + } } } - // AddCallback internally grabs OpenTelemetry's observable_registry's lock. So - // we need to call it without our plugin lock otherwise we may deadlock. + // AddCallback internally grabs OpenTelemetry's observable_registry's + // lock. So we need to call it without our plugin lock otherwise we may + // deadlock. for (const auto& gauge : gauges_that_need_to_add_callback) { grpc_core::Match( gauge, @@ -759,50 +774,59 @@ void OpenTelemetryPlugin::RemoveCallback( grpc_core::MutexLock lock(&mu_); callback_timestamps_.erase(callback); for (const auto& handle : callback->metrics()) { - grpc_core::Match( - handle, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackInt64GaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - CHECK((*callback_gauge_state)->ot_callback_registered); - CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); - if ((*callback_gauge_state)->caches.empty()) { - gauges_that_need_to_remove_callback.push_back( - callback_gauge_state->get()); - (*callback_gauge_state)->ot_callback_registered = false; - } - }, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackDoubleGaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - CHECK((*callback_gauge_state)->ot_callback_registered); - CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); - if ((*callback_gauge_state)->caches.empty()) { - gauges_that_need_to_remove_callback.push_back( - callback_gauge_state->get()); - (*callback_gauge_state)->ot_callback_registered = false; - } - }); + const auto& descriptor = + grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle); + GPR_ASSERT( + descriptor.instrument_type == + grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); + switch (descriptor.value_type) { + case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + CHECK((*callback_gauge_state)->ot_callback_registered); + CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); + if ((*callback_gauge_state)->caches.empty()) { + gauges_that_need_to_remove_callback.push_back( + callback_gauge_state->get()); + (*callback_gauge_state)->ot_callback_registered = false; + } + break; + } + case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + CHECK((*callback_gauge_state)->ot_callback_registered); + CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); + if ((*callback_gauge_state)->caches.empty()) { + gauges_that_need_to_remove_callback.push_back( + callback_gauge_state->get()); + (*callback_gauge_state)->ot_callback_registered = false; + } + break; + } + default: + grpc_core::Crash(absl::StrFormat( + "Unknown or unsupported value type: %d", descriptor.value_type)); + } } } - // RemoveCallback internally grabs OpenTelemetry's observable_registry's lock. - // So we need to call it without our plugin lock otherwise we may deadlock. + // RemoveCallback internally grabs OpenTelemetry's observable_registry's + // lock. So we need to call it without our plugin lock otherwise we may + // deadlock. for (const auto& gauge : gauges_that_need_to_remove_callback) { grpc_core::Match( gauge, @@ -842,7 +866,8 @@ void OpenTelemetryPlugin::CallbackGaugeState::Observe( } } -// OpenTelemetry calls our callback with its observable_registry's lock held. +// OpenTelemetry calls our callback with its observable_registry's lock +// held. template void OpenTelemetryPlugin::CallbackGaugeState::CallbackGaugeCallback( opentelemetry::metrics::ObserverResult result, void* arg) { diff --git a/src/cpp/ext/otel/otel_plugin.h b/src/cpp/ext/otel/otel_plugin.h index 6908f2b7ab4..49d2cc3e384 100644 --- a/src/cpp/ext/otel/otel_plugin.h +++ b/src/cpp/ext/otel/otel_plugin.h @@ -343,22 +343,20 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin { grpc_core::RegisteredMetricCallback* key) ABSL_EXCLUSIVE_LOCKS_REQUIRED(ot_plugin->mu_); - void Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle - handle, + private: + void ReportInt64( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, absl::Span label_values, absl::Span optional_values) ABSL_EXCLUSIVE_LOCKS_REQUIRED( CallbackGaugeState::ot_plugin->mu_) override; - void Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle - handle, + void ReportDouble( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) ABSL_EXCLUSIVE_LOCKS_REQUIRED( CallbackGaugeState::ot_plugin->mu_) override; - private: OpenTelemetryPlugin* ot_plugin_; grpc_core::RegisteredMetricCallback* key_; }; @@ -380,19 +378,19 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin { std::pair> IsEnabledForServer(const grpc_core::ChannelArgs& args) const override; void AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) override; void AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) override; void RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) override; void RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) override; void AddCallback(grpc_core::RegisteredMetricCallback* callback) diff --git a/test/core/channel/metrics_test.cc b/test/core/channel/metrics_test.cc index d6b4d04d17c..20b915c7904 100644 --- a/test/core/channel/metrics_test.cc +++ b/test/core/channel/metrics_test.cc @@ -16,10 +16,6 @@ #include -#include "absl/container/flat_hash_map.h" -#include "absl/strings/match.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_join.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -40,15 +36,15 @@ class MetricsTest : public ::testing::Test { }; TEST_F(MetricsTest, UInt64Counter) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; - auto uint64_counter_handle = GlobalInstrumentsRegistry::RegisterUInt64Counter( - "uint64_counter", "A simple uint64 counter.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + auto uint64_counter_handle = + GlobalInstrumentsRegistry::RegisterUInt64Counter( + "uint64_counter", "A simple uint64 counter.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -58,34 +54,37 @@ TEST_F(MetricsTest, UInt64Counter) { auto plugin3 = MakeStatsPluginForTarget(kDomain3To4); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")) - .AddCounter(uint64_counter_handle, 1, kLabelValues, kOptionalLabelValues); + .AddCounter(uint64_counter_handle, uint64_t(1), kLabelValues, + kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")) - .AddCounter(uint64_counter_handle, 2, kLabelValues, kOptionalLabelValues); + .AddCounter(uint64_counter_handle, uint64_t(2), kLabelValues, + kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")) - .AddCounter(uint64_counter_handle, 3, kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetCounterValue(uint64_counter_handle, kLabelValues, - kOptionalLabelValues), + .AddCounter(uint64_counter_handle, uint64_t(3), kLabelValues, + kOptionalLabelValues); + EXPECT_THAT(plugin1->GetUInt64CounterValue( + uint64_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1)); - EXPECT_THAT(plugin2->GetCounterValue(uint64_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetUInt64CounterValue( + uint64_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin3->GetCounterValue(uint64_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetUInt64CounterValue( + uint64_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(6)); } TEST_F(MetricsTest, DoubleCounter) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; - auto double_counter_handle = GlobalInstrumentsRegistry::RegisterDoubleCounter( - "double_counter", "A simple double counter.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + auto double_counter_handle = + GlobalInstrumentsRegistry::RegisterDoubleCounter( + "double_counter", "A simple double counter.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -105,28 +104,27 @@ TEST_F(MetricsTest, DoubleCounter) { StatsPluginChannelScope(kDomain3To4, "")) .AddCounter(double_counter_handle, 3.45, kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetCounterValue(double_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCounterValue( + double_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1.23)); - EXPECT_THAT(plugin2->GetCounterValue(double_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCounterValue( + double_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.57)); - EXPECT_THAT(plugin3->GetCounterValue(double_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetDoubleCounterValue( + double_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(7.02)); } TEST_F(MetricsTest, UInt64Histogram) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto uint64_histogram_handle = GlobalInstrumentsRegistry::RegisterUInt64Histogram( - "uint64_histogram", "A simple uint64 histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "uint64_histogram", "A simple uint64 histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -136,38 +134,37 @@ TEST_F(MetricsTest, UInt64Histogram) { auto plugin3 = MakeStatsPluginForTarget(kDomain3To4); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")) - .RecordHistogram(uint64_histogram_handle, 1, kLabelValues, + .RecordHistogram(uint64_histogram_handle, uint64_t(1), kLabelValues, kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")) - .RecordHistogram(uint64_histogram_handle, 2, kLabelValues, + .RecordHistogram(uint64_histogram_handle, uint64_t(2), kLabelValues, kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")) - .RecordHistogram(uint64_histogram_handle, 3, kLabelValues, + .RecordHistogram(uint64_histogram_handle, uint64_t(3), kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetHistogramValue(uint64_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetUInt64HistogramValue( + uint64_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1))); - EXPECT_THAT(plugin2->GetHistogramValue(uint64_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetUInt64HistogramValue( + uint64_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1, 2))); - EXPECT_THAT(plugin3->GetHistogramValue(uint64_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetUInt64HistogramValue( + uint64_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1, 2, 3))); } TEST_F(MetricsTest, DoubleHistogram) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto double_histogram_handle = GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "double_histogram", "A simple double histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -187,31 +184,30 @@ TEST_F(MetricsTest, DoubleHistogram) { StatsPluginChannelScope(kDomain3To4, "")) .RecordHistogram(double_histogram_handle, 3.45, kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleHistogramValue( + double_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1.23))); - EXPECT_THAT(plugin2->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleHistogramValue( + double_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34))); EXPECT_THAT( - plugin3->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + plugin3->GetDoubleHistogramValue(double_histogram_handle, kLabelValues, + kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34, 3.45))); } TEST_F(MetricsTest, Int64CallbackGauge) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto int64_gauge_handle = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( - "int64_gauge", "A simple int64 gauge.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kLabelValues2[] = {"label_value_3", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "int64_gauge", "A simple int64 gauge.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kLabelValues2 = {"label_value_3", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -226,57 +222,57 @@ TEST_F(MetricsTest, Int64CallbackGauge) { StatsPluginChannelScope(kDomain3To4, "")); auto callback1 = group1.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 1, kLabelValues, + reporter.Report(int64_gauge_handle, int64_t(1), kLabelValues, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); auto callback2 = group1.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 2, kLabelValues2, + reporter.Report(int64_gauge_handle, int64_t(2), kLabelValues2, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); // No plugins have data yet. - EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 should have data, but the others should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); @@ -287,57 +283,57 @@ TEST_F(MetricsTest, Int64CallbackGauge) { StatsPluginChannelScope(kDomain2To4, "")); callback1 = group2.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 3, kLabelValues, + reporter.Report(int64_gauge_handle, int64_t(3), kLabelValues, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); callback2 = group2.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 4, kLabelValues2, + reporter.Report(int64_gauge_handle, int64_t(4), kLabelValues2, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); // Plugin1 still has data from before, but the others have none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); @@ -348,57 +344,57 @@ TEST_F(MetricsTest, Int64CallbackGauge) { StatsPluginChannelScope(kDomain1To4, "")); callback1 = group3.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 5, kLabelValues, + reporter.Report(int64_gauge_handle, int64_t(5), kLabelValues, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); callback2 = group3.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 6, kLabelValues2, + reporter.Report(int64_gauge_handle, int64_t(6), kLabelValues2, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); // Plugin1 and plugin2 still has data from before, but plugin3 has none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6)); // Need to destroy callbacks before the plugin group that created them. callback1.reset(); @@ -406,18 +402,17 @@ TEST_F(MetricsTest, Int64CallbackGauge) { } TEST_F(MetricsTest, DoubleCallbackGauge) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto double_gauge_handle = GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( - "double_gauge", "A simple double gauge.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kLabelValues2[] = {"label_value_3", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "double_gauge", "A simple double gauge.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kLabelValues2 = {"label_value_3", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -435,54 +430,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { reporter.Report(double_gauge_handle, 1.23, kLabelValues, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); auto callback2 = group1.RegisterCallback( [&](CallbackMetricReporter& reporter) { reporter.Report(double_gauge_handle, 2.34, kLabelValues2, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); // No plugins have data yet. - EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 should have data, but the others should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1.23)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2.34)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); @@ -496,54 +491,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { reporter.Report(double_gauge_handle, 3.45, kLabelValues, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); callback2 = group2.RegisterCallback( [&](CallbackMetricReporter& reporter) { reporter.Report(double_gauge_handle, 4.56, kLabelValues2, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); // Plugin1 still has data from before, but the others have none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1.23)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2.34)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); @@ -557,54 +552,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { reporter.Report(double_gauge_handle, 5.67, kLabelValues, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); callback2 = group3.RegisterCallback( [&](CallbackMetricReporter& reporter) { reporter.Report(double_gauge_handle, 6.78, kLabelValues2, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); // Plugin1 and plugin2 still has data from before, but plugin3 has none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5.67)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6.78)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5.67)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6.78)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5.67)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6.78)); // Need to destroy callbacks before the plugin group that created them. callback1.reset(); @@ -612,16 +607,15 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { } TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto double_histogram_handle = GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/false); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "double_histogram", "A simple double histogram.", "unit", false) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; auto plugin = MakeStatsPluginForTarget(kDomain1To4); @@ -629,24 +623,26 @@ TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) { StatsPluginChannelScope(kDomain1To4, "")) .RecordHistogram(double_histogram_handle, 1.23, kLabelValues, kOptionalLabelValues); - EXPECT_EQ(plugin->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin->GetDoubleHistogramValue(double_histogram_handle, + kLabelValues, kOptionalLabelValues), absl::nullopt); } using MetricsDeathTest = MetricsTest; TEST_F(MetricsDeathTest, RegisterTheSameMetricNameWouldCrash) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; (void)GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - EXPECT_DEATH(GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", - kLabelKeys, kOptionalLabelKeys, true), - "Metric name double_histogram has already been registered."); + "double_histogram", "A simple double histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + EXPECT_DEATH( + GlobalInstrumentsRegistry::RegisterDoubleHistogram( + "double_histogram", "A simple double histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(), + "Metric name double_histogram has already been registered."); } } // namespace diff --git a/test/core/load_balancing/pick_first_test.cc b/test/core/load_balancing/pick_first_test.cc index e3dfd04ffc9..839afa62a3c 100644 --- a/test/core/load_balancing/pick_first_test.cc +++ b/test/core/load_balancing/pick_first_test.cc @@ -1307,8 +1307,8 @@ TEST_F(PickFirstTest, MetricValues) { // The first subchannel's connection attempt fails. subchannel->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE, absl::UnavailableError("failed to connect")); - EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsFailed, - kLabelValues, {}), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsFailed, + kLabelValues, {}), ::testing::Optional(1)); // The LB policy will start a connection attempt on the second subchannel. EXPECT_TRUE(subchannel2->ConnectionRequested()); @@ -1317,8 +1317,8 @@ TEST_F(PickFirstTest, MetricValues) { subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); // The connection attempt succeeds. subchannel2->SetConnectivityState(GRPC_CHANNEL_READY); - EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsSucceeded, - kLabelValues, {}), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsSucceeded, + kLabelValues, {}), ::testing::Optional(1)); // The LB policy will report CONNECTING some number of times (doesn't // matter how many) and then report READY. @@ -1332,8 +1332,9 @@ TEST_F(PickFirstTest, MetricValues) { subchannel2->SetConnectivityState(GRPC_CHANNEL_IDLE); ExpectReresolutionRequest(); ExpectState(GRPC_CHANNEL_IDLE); - EXPECT_THAT(stats_plugin->GetCounterValue(kDisconnections, kLabelValues, {}), - ::testing::Optional(1)); + EXPECT_THAT( + stats_plugin->GetUInt64CounterValue(kDisconnections, kLabelValues, {}), + ::testing::Optional(1)); } class PickFirstHealthCheckingEnabledTest : public PickFirstTest { diff --git a/test/core/load_balancing/weighted_round_robin_test.cc b/test/core/load_balancing/weighted_round_robin_test.cc index 9177562e919..9a5eebba751 100644 --- a/test/core/load_balancing/weighted_round_robin_test.cc +++ b/test/core/load_balancing/weighted_round_robin_test.cc @@ -1113,8 +1113,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) { /*qps=*/100.0, /*eps=*/0.0)}}, {{kAddresses[0], 1}, {kAddresses[1], 3}, {kAddresses[2], 3}}); // Check endpoint weights. - EXPECT_THAT(stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetDoubleHistogramValue( + kEndpointWeights, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::ElementsAre( // Picker created for first endpoint becoming READY. 0, @@ -1135,17 +1135,18 @@ TEST_F(WeightedRoundRobinTest, MetricValues) { ::testing::DoubleNear(333.333344, 0.000001)))); // RR fallback should trigger for the first 5 updates above, because // there are less than two endpoints with valid weights. - EXPECT_THAT(stats_plugin->GetCounterValue(kRrFallback, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kRrFallback, kLabelValues, + kOptionalLabelValues), ::testing::Optional(5)); // Endpoint-not-yet-usable will be incremented once for every endpoint // with weight 0 above. - EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightNotYetUsable, - kLabelValues, kOptionalLabelValues), - ::testing::Optional(10)); + EXPECT_THAT( + stats_plugin->GetUInt64CounterValue(kEndpointWeightNotYetUsable, + kLabelValues, kOptionalLabelValues), + ::testing::Optional(10)); // There are no stale endpoint weights so far. - EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue( + kEndpointWeightStale, kLabelValues, kOptionalLabelValues), ::testing::Optional(0)); // Advance time to make weights stale and trigger the timer callback // to recompute weights. @@ -1156,8 +1157,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) { picker.get(), {}, {{kAddresses[0], 3}, {kAddresses[1], 3}, {kAddresses[2], 3}}); // All three endpoints should now have stale weights. - EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue( + kEndpointWeightStale, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); } diff --git a/test/core/test_util/fake_stats_plugin.cc b/test/core/test_util/fake_stats_plugin.cc index 50b86a278cc..abc0a6a82ff 100644 --- a/test/core/test_util/fake_stats_plugin.cc +++ b/test/core/test_util/fake_stats_plugin.cc @@ -125,8 +125,8 @@ void GlobalInstrumentsRegistryTestPeer::ResetGlobalInstrumentsRegistry() { namespace { -template -absl::optional FindInstrument( +absl::optional +FindInstrument( const std::vector& instruments, absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type, @@ -134,7 +134,7 @@ absl::optional FindInstrument( for (const auto& descriptor : instruments) { if (descriptor.name == name && descriptor.value_type == value_type && descriptor.instrument_type == instrument_type) { - HandleType handle; + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle; handle.index = descriptor.index; return handle; } @@ -144,57 +144,51 @@ absl::optional FindInstrument( } // namespace -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindUInt64CounterHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kUInt64, - GlobalInstrumentsRegistry::InstrumentType::kCounter); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kCounter); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindDoubleCounterHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kDouble, - GlobalInstrumentsRegistry::InstrumentType::kCounter); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kCounter); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindUInt64HistogramHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kUInt64, - GlobalInstrumentsRegistry::InstrumentType::kHistogram); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kHistogram); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindDoubleHistogramHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kDouble, - GlobalInstrumentsRegistry::InstrumentType::kHistogram); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kHistogram); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindCallbackInt64GaugeHandleByName( absl::string_view name) { - return FindInstrument< - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>( + return FindInstrument( GlobalInstrumentsRegistry::GetInstrumentList(), name, GlobalInstrumentsRegistry::ValueType::kInt64, GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName( absl::string_view name) { - return FindInstrument< - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>( + return FindInstrument( GlobalInstrumentsRegistry::GetInstrumentList(), name, GlobalInstrumentsRegistry::ValueType::kDouble, GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); diff --git a/test/core/test_util/fake_stats_plugin.h b/test/core/test_util/fake_stats_plugin.h index 29a793dc5c3..655dfe0002c 100644 --- a/test/core/test_util/fake_stats_plugin.h +++ b/test/core/test_util/fake_stats_plugin.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "absl/container/flat_hash_map.h" @@ -270,8 +271,8 @@ class FakeStatsPlugin : public StatsPlugin { } void AddCounter( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_values) override { // The problem with this approach is that we initialize uint64_counters_ in // BuildAndRegister by querying the GlobalInstrumentsRegistry at the time. @@ -283,7 +284,8 @@ class FakeStatsPlugin : public StatsPlugin { // GlobalInstrumentsRegistry everytime a metric is recorded. But this is not // a concern for now. gpr_log(GPR_INFO, - "FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%lu, " + "FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%" PRIu64 + ", " "label_values={%s}, optional_label_values={%s}", this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(), @@ -294,7 +296,7 @@ class FakeStatsPlugin : public StatsPlugin { iter->second.Add(value, label_values, optional_values); } void AddCounter( - GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, @@ -309,23 +311,24 @@ class FakeStatsPlugin : public StatsPlugin { iter->second.Add(value, label_values, optional_values); } void RecordHistogram( - GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_values) override { - gpr_log(GPR_INFO, - "FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%lu, " - "label_values={%s}, optional_label_values={%s}", - this, handle.index, value, - absl::StrJoin(label_values, ", ").c_str(), - absl::StrJoin(optional_values, ", ").c_str()); + gpr_log( + GPR_INFO, + "FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%" PRIu64 + ", " + "label_values={%s}, optional_label_values={%s}", + this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(), + absl::StrJoin(optional_values, ", ").c_str()); MutexLock lock(&mu_); auto iter = uint64_histograms_.find(handle.index); if (iter == uint64_histograms_.end()) return; iter->second.Record(value, label_values, optional_values); } void RecordHistogram( - GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, - double value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(double)%f, " @@ -358,8 +361,8 @@ class FakeStatsPlugin : public StatsPlugin { return nullptr; } - absl::optional GetCounterValue( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, + absl::optional GetUInt64CounterValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -369,8 +372,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValue(label_values, optional_values); } - absl::optional GetCounterValue( - GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, + absl::optional GetDoubleCounterValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -380,8 +383,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValue(label_values, optional_values); } - absl::optional> GetHistogramValue( - GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, + absl::optional> GetUInt64HistogramValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -391,8 +394,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValues(label_values, optional_values); } - absl::optional> GetHistogramValue( - GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, + absl::optional> GetDoubleHistogramValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -410,8 +413,8 @@ class FakeStatsPlugin : public StatsPlugin { } gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::TriggerCallbacks(): END", this); } - absl::optional GetCallbackGaugeValue( - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, + absl::optional GetInt64CallbackGaugeValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&callback_mu_); @@ -421,8 +424,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValue(label_values, optional_values); } - absl::optional GetCallbackGaugeValue( - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle, + absl::optional GetDoubleCallbackGaugeValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&callback_mu_); @@ -438,13 +441,14 @@ class FakeStatsPlugin : public StatsPlugin { public: explicit Reporter(FakeStatsPlugin& plugin) : plugin_(plugin) {} - void Report( - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, - int64_t value, absl::Span label_values, + void ReportInt64( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, + absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::Reporter::Report(index=%u, " - "value=(uint64)%ld, label_values={%s}, " + "value=(int64_t)%" PRId64 + ", label_values={%s}, " "optional_label_values={%s}", this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(), @@ -455,9 +459,9 @@ class FakeStatsPlugin : public StatsPlugin { iter->second.Set(value, label_values, optional_values); } - void Report( - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle, - double value, absl::Span label_values, + void ReportDouble( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::Reporter::Report(index=%u, " @@ -654,19 +658,17 @@ class GlobalInstrumentsRegistryTestPeer { public: static void ResetGlobalInstrumentsRegistry(); - static absl::optional + static absl::optional FindUInt64CounterHandleByName(absl::string_view name); - static absl::optional + static absl::optional FindDoubleCounterHandleByName(absl::string_view name); - static absl::optional + static absl::optional FindUInt64HistogramHandleByName(absl::string_view name); - static absl::optional + static absl::optional FindDoubleHistogramHandleByName(absl::string_view name); - static absl::optional< - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle> + static absl::optional FindCallbackInt64GaugeHandleByName(absl::string_view name); - static absl::optional< - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle> + static absl::optional FindCallbackDoubleGaugeHandleByName(absl::string_view name); static GlobalInstrumentsRegistry::GlobalInstrumentDescriptor* diff --git a/test/cpp/end2end/rls_end2end_test.cc b/test/cpp/end2end/rls_end2end_test.cc index 189c4c2d34c..ca6616fe6b7 100644 --- a/test/cpp/end2end/rls_end2end_test.cc +++ b/test/cpp/end2end/rls_end2end_test.cc @@ -1535,24 +1535,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) { EXPECT_EQ(backends_[1]->service_.request_count(), 0); // Check exported metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target0, "complete"}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target1, "complete"}, {}), absl::nullopt); - EXPECT_EQ(stats_plugin_->GetCounterValue( + EXPECT_EQ(stats_plugin_->GetUInt64CounterValue( kMetricFailedPicks, {target_uri_, rls_server_target_}, {}), absl::nullopt); stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheEntries, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}), ::testing::Optional(1)); - auto cache_size = stats_plugin_->GetCallbackGaugeValue( + auto cache_size = stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}); EXPECT_THAT(cache_size, ::testing::Optional(::testing::Ge(1))); @@ -1567,24 +1567,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) { EXPECT_EQ(backends_[1]->service_.request_count(), 1); // Check exported metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target0, "complete"}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target1, "complete"}, {}), ::testing::Optional(1)); - EXPECT_EQ(stats_plugin_->GetCounterValue( + EXPECT_EQ(stats_plugin_->GetUInt64CounterValue( kMetricFailedPicks, {target_uri_, rls_server_target_}, {}), absl::nullopt); stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheEntries, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}), ::testing::Optional(2)); - auto cache_size2 = stats_plugin_->GetCallbackGaugeValue( + auto cache_size2 = stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}); EXPECT_THAT(cache_size2, ::testing::Optional(::testing::Ge(2))); @@ -1611,24 +1611,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) { EXPECT_EQ(backends_[1]->service_.request_count(), 1); // Check exported metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target0, "complete"}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target1, "complete"}, {}), ::testing::Optional(1)); - EXPECT_THAT(stats_plugin_->GetCounterValue( + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue( kMetricFailedPicks, {target_uri_, rls_server_target_}, {}), ::testing::Optional(1)); stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheEntries, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}), ::testing::Optional(3)); - auto cache_size3 = stats_plugin_->GetCallbackGaugeValue( + auto cache_size3 = stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}); EXPECT_THAT(cache_size3, ::testing::Optional(::testing::Ge(3))); @@ -1678,7 +1678,7 @@ TEST_F(RlsMetricsEnd2endTest, MetricValuesDefaultTargetRpcs) { EXPECT_EQ(backends_[0]->service_.request_count(), 1); // Check expected metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricDefaultTargetPicks, {target_uri_, rls_server_target_, default_target, "complete"}, {}), ::testing::Optional(1)); diff --git a/test/cpp/end2end/xds/xds_core_end2end_test.cc b/test/cpp/end2end/xds/xds_core_end2end_test.cc index fd9cc6cac2d..ebc97f4a8e8 100644 --- a/test/cpp/end2end/xds/xds_core_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_core_end2end_test.cc @@ -1217,11 +1217,11 @@ TEST_P(XdsMetricsTest, MetricValues) { CheckRpcSendOk(DEBUG_LOCATION); stats_plugin_->TriggerCallbacks(); // Check client metrics. - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected, - {kTarget, kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( + kMetricConnected, {kTarget, kXdsServer}, {}), ::testing::Optional(1)); - EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure, - {kTarget, kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure, + {kTarget, kXdsServer}, {}), absl::nullopt); for (absl::string_view type_url : {"envoy.config.listener.v3.Listener", @@ -1229,37 +1229,37 @@ TEST_P(XdsMetricsTest, MetricValues) { "envoy.config.cluster.v3.Cluster", "envoy.config.endpoint.v3.ClusterLoadAssignment"}) { EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid, - {kTarget, kXdsServer, type_url}, {}), + stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesValid, {kTarget, kXdsServer, type_url}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid, - {kTarget, kXdsServer, type_url}, {}), + stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesInvalid, {kTarget, kXdsServer, type_url}, {}), ::testing::Optional(0)); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricResources, {kTarget, "#old", type_url, "acked"}, {}), ::testing::Optional(1)); } // Check server metrics. - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected, - {"#server", kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( + kMetricConnected, {"#server", kXdsServer}, {}), ::testing::Optional(1)); - EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure, - {"#server", kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure, + {"#server", kXdsServer}, {}), absl::nullopt); for (absl::string_view type_url : {"envoy.config.listener.v3.Listener", "envoy.config.route.v3.RouteConfiguration"}) { EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid, - {"#server", kXdsServer, type_url}, {}), + stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesValid, {"#server", kXdsServer, type_url}, {}), ::testing::Optional(1)); + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesInvalid, + {"#server", kXdsServer, type_url}, {}), + ::testing::Optional(0)); EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid, - {"#server", kXdsServer, type_url}, {}), - ::testing::Optional(0)); - EXPECT_THAT( - stats_plugin_->GetCallbackGaugeValue( + stats_plugin_->GetInt64CallbackGaugeValue( kMetricResources, {"#server", "#old", type_url, "acked"}, {}), ::testing::Optional(1)); } @@ -1269,8 +1269,8 @@ TEST_P(XdsMetricsTest, MetricValues) { const absl::Time deadline = absl::Now() + absl::Seconds(5 * grpc_test_slowdown_factor()); while (true) { - auto value = stats_plugin_->GetCounterValue(kMetricServerFailure, - {target, kXdsServer}, {}); + auto value = stats_plugin_->GetUInt64CounterValue( + kMetricServerFailure, {target, kXdsServer}, {}); if (value.has_value()) { EXPECT_EQ(1, *value); break; @@ -1279,8 +1279,8 @@ TEST_P(XdsMetricsTest, MetricValues) { absl::SleepFor(absl::Seconds(1)); } stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected, - {target, kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( + kMetricConnected, {target, kXdsServer}, {}), ::testing::Optional(0)); } } diff --git a/test/cpp/end2end/xds/xds_wrr_end2end_test.cc b/test/cpp/end2end/xds/xds_wrr_end2end_test.cc index 97c5b6ab9a1..9a58443efa0 100644 --- a/test/cpp/end2end/xds/xds_wrr_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_wrr_end2end_test.cc @@ -132,12 +132,12 @@ TEST_P(WrrTest, MetricsHaveLocalityLabel) { WaitForAllBackends(DEBUG_LOCATION); // Make sure we have a metric value for each of the two localities. EXPECT_THAT( - stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues, - {LocalityNameString("locality0")}), + stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues, + {LocalityNameString("locality0")}), ::testing::Optional(::testing::Not(::testing::IsEmpty()))); EXPECT_THAT( - stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues, - {LocalityNameString("locality1")}), + stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues, + {LocalityNameString("locality1")}), ::testing::Optional(::testing::Not(::testing::IsEmpty()))); } diff --git a/test/cpp/ext/otel/otel_plugin_test.cc b/test/cpp/ext/otel/otel_plugin_test.cc index af24fcabcac..e616f075d13 100644 --- a/test/cpp/ext/otel/otel_plugin_test.cc +++ b/test/cpp/ext/otel/otel_plugin_test.cc @@ -1263,7 +1263,7 @@ using OpenTelemetryPluginNPCMetricsTest = OpenTelemetryPluginEnd2EndTest; TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) { constexpr absl::string_view kMetricName = "uint64_counter"; - constexpr int kCounterValues[] = {1, 2, 3}; + constexpr uint64_t kCounterValues[] = {1, 2, 3}; constexpr int64_t kCounterResult = 6; constexpr std::array kLabelKeys = {"label_key_1", "label_key_2"}; @@ -1273,9 +1273,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter( - kMetricName, "A simple uint64 counter.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter( + kMetricName, "A simple uint64 counter.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kMetricName}) .set_channel_scope_filter( @@ -1319,9 +1323,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter( - kMetricName, "A simple double counter.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/false); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter( + kMetricName, "A simple double counter.", "unit", + /*enable_by_default=*/false) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kMetricName}) .set_channel_scope_filter( @@ -1355,7 +1363,7 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) { TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) { constexpr absl::string_view kMetricName = "uint64_histogram"; - constexpr int kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6}; + constexpr uint64_t kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6}; constexpr int64_t kSum = 26; constexpr int64_t kMin = 1; constexpr int64_t kMax = 6; @@ -1368,9 +1376,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram( - kMetricName, "A simple uint64 histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram( + kMetricName, "A simple uint64 histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move( Options() .set_metric_names({kMetricName}) @@ -1419,9 +1431,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleHistogram) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( - kMetricName, "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( + kMetricName, "A simple double histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move( Options() .set_metric_names({kMetricName}) @@ -1466,9 +1482,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( - kMetricName, "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( + kMetricName, "A simple double histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); // Build and register a separate OpenTelemetryPlugin and verify its histogram // recording. grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder; @@ -1592,9 +1612,14 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, constexpr std::array kActualOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2", "optional_label_value_4"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( - kMetricName, "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( + kMetricName, "A simple double histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1], + kOptionalLabelKeys[2], kOptionalLabelKeys[3]) + .Build(); Init(std::move( Options() .set_metric_names({kMetricName}) @@ -1655,13 +1680,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, auto integer_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); auto double_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kInt64CallbackGaugeMetric, kDoubleCallbackGaugeMetric}) @@ -1671,8 +1700,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel( grpc_core::experimental::StatsPluginChannelScope( "dns:///localhost:8080", "")); - // Multiple callbacks for the same metrics, each reporting different label - // values. + // Multiple callbacks for the same metrics, each reporting different + // label values. int report_count_1 = 0; int64_t int_value_1 = 1; double double_value_1 = 0.5; @@ -1688,8 +1717,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); int report_count_2 = 0; int64_t int_value_2 = 1; double double_value_2 = 0.5; @@ -1705,8 +1734,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); constexpr int kIterations = 100; MetricsCollectorThread collector{ this, grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(), @@ -1786,13 +1815,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, auto integer_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); auto double_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kInt64CallbackGaugeMetric, kDoubleCallbackGaugeMetric}) @@ -1802,8 +1835,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel( grpc_core::experimental::StatsPluginChannelScope( "dns:///localhost:8080", "")); - // Multiple callbacks for the same metrics, each reporting different label - // values. + // Multiple callbacks for the same metrics, each reporting different + // label values. int report_count_1 = 0; int64_t int_value_1 = 1; double double_value_1 = 0.5; @@ -1819,8 +1852,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); int report_count_2 = 0; int64_t int_value_2 = 1; double double_value_2 = 0.5; @@ -1836,8 +1869,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); constexpr int kIterations = 100; MetricsCollectorThread collector{ this, @@ -1854,7 +1887,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, std::string, std::vector> data = collector.Stop(); - // Verify that data is incremental without duplications (cached values). + // Verify that data is incremental without duplications (cached + // values). EXPECT_EQ(report_count_1, kIterations); EXPECT_EQ(report_count_2, kIterations); EXPECT_EQ(data[kInt64CallbackGaugeMetric].size(), From b943668f95268827966fa546c2611277360b9578 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Thu, 9 May 2024 22:16:01 -0700 Subject: [PATCH 16/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36570) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36570 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36570 from tanvi-jagtap:test_cpp_interop_tjagtap c50744629540020e2bb0e27158a6437d82c5bc64 PiperOrigin-RevId: 632375773 --- test/cpp/interop/BUILD | 2 ++ test/cpp/interop/grpclb_fallback_test.cc | 40 +++++++++++------------- test/cpp/interop/http2_client.cc | 33 +++++++++---------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 76b49f88be9..21d86d04971 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -46,6 +46,7 @@ grpc_cc_binary( external_deps = [ "absl/flags:flag", "absl/log:check", + "absl/log:log", "absl/time:time", ], language = "C++", @@ -429,6 +430,7 @@ grpc_cc_binary( external_deps = [ "absl/flags:flag", "absl/log:check", + "absl/log:log", ], deps = [ "//:grpc++", diff --git a/test/cpp/interop/grpclb_fallback_test.cc b/test/cpp/interop/grpclb_fallback_test.cc index c8e20fdc54e..331885e8c0f 100644 --- a/test/cpp/interop/grpclb_fallback_test.cc +++ b/test/cpp/interop/grpclb_fallback_test.cc @@ -32,11 +32,11 @@ #include "absl/flags/flag.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_format.h" #include "absl/time/time.h" #include -#include #include #include #include @@ -87,8 +87,8 @@ enum RpcMode { GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds, RpcMode rpc_mode) { - gpr_log(GPR_INFO, "DoRPCAndGetPath deadline_seconds:%d rpc_mode:%d", - deadline_seconds, rpc_mode); + LOG(INFO) << "DoRPCAndGetPath deadline_seconds:" << deadline_seconds + << " rpc_mode:" << rpc_mode; SimpleRequest request; SimpleResponse response; grpc::ClientContext context; @@ -101,16 +101,16 @@ GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds, context.set_deadline(deadline); grpc::Status s = stub->UnaryCall(&context, request, &response); if (!s.ok()) { - gpr_log(GPR_INFO, "DoRPCAndGetPath failed. status-message: %s", - s.error_message().c_str()); + LOG(INFO) << "DoRPCAndGetPath failed. status-message: " + << s.error_message(); return GrpclbRouteType::GRPCLB_ROUTE_TYPE_UNKNOWN; } CHECK(response.grpclb_route_type() == GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND || response.grpclb_route_type() == GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK); - gpr_log(GPR_INFO, "DoRPCAndGetPath done. grpclb_route_type:%d", - response.grpclb_route_type()); + LOG(INFO) << "DoRPCAndGetPath done. grpclb_route_type:" + << response.grpclb_route_type(); return response.grpclb_route_type(); } @@ -120,7 +120,7 @@ GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds) { bool TcpUserTimeoutMutateFd(int fd, grpc_socket_mutator* /*mutator*/) { int timeout = 20000; // 20 seconds - gpr_log(GPR_INFO, "Setting socket option TCP_USER_TIMEOUT on fd: %d", fd); + LOG(INFO) << "Setting socket option TCP_USER_TIMEOUT on fd: " << fd; if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, sizeof(timeout))) { grpc_core::Crash("Failed to set socket option TCP_USER_TIMEOUT"); @@ -161,7 +161,7 @@ std::unique_ptr CreateFallbackTestStub() { } void RunCommand(const std::string& command) { - gpr_log(GPR_INFO, "RunCommand: |%s|", command.c_str()); + LOG(INFO) << "RunCommand: |" << command << "|"; int out = std::system(command.c_str()); if (WIFEXITED(out)) { int code = WEXITSTATUS(out); @@ -185,25 +185,23 @@ void WaitForFallbackAndDoRPCs(TestService::Stub* stub) { while (absl::Now() < fallback_deadline) { GrpclbRouteType grpclb_route_type = DoRPCAndGetPath(stub, 1); if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND) { - gpr_log(GPR_ERROR, - "Got grpclb route type backend. Backends are " - "supposed to be unreachable, so this test is broken"); + LOG(ERROR) << "Got grpclb route type backend. Backends are " + "supposed to be unreachable, so this test is broken"; CHECK(0); } if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK) { - gpr_log(GPR_INFO, - "Made one successful RPC to a fallback. Now expect the same for " - "the rest."); + LOG(INFO) << "Made one successful RPC to a fallback. Now expect the same " + "for the rest."; fallback = true; break; } else { - gpr_log(GPR_ERROR, "Retryable RPC failure on iteration: %d", - fallback_retry_count); + LOG(ERROR) << "Retryable RPC failure on iteration: " + << fallback_retry_count; } fallback_retry_count++; } if (!fallback) { - gpr_log(GPR_ERROR, "Didn't fall back within deadline"); + LOG(ERROR) << "Didn't fall back within deadline"; CHECK(0); } for (int i = 0; i < 30; i++) { @@ -231,13 +229,13 @@ void DoFallbackAfterStartupTest() { int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - gpr_log(GPR_INFO, "Testing: %s", absl::GetFlag(FLAGS_test_case).c_str()); + LOG(INFO) << "Testing: " << absl::GetFlag(FLAGS_test_case); if (absl::GetFlag(FLAGS_test_case) == "fallback_before_startup") { DoFallbackBeforeStartupTest(); - gpr_log(GPR_INFO, "DoFallbackBeforeStartup done!"); + LOG(INFO) << "DoFallbackBeforeStartup done!"; } else if (absl::GetFlag(FLAGS_test_case) == "fallback_after_startup") { DoFallbackAfterStartupTest(); - gpr_log(GPR_INFO, "DoFallbackBeforeStartup done!"); + LOG(INFO) << "DoFallbackBeforeStartup done!"; } else { grpc_core::Crash(absl::StrFormat("Invalid test case: %s", absl::GetFlag(FLAGS_test_case).c_str())); diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc index eb96a08b715..89477f3cd51 100644 --- a/test/cpp/interop/http2_client.cc +++ b/test/cpp/interop/http2_client.cc @@ -22,10 +22,10 @@ #include "absl/flags/flag.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_format.h" #include -#include #include #include @@ -81,40 +81,40 @@ SimpleRequest Http2Client::BuildDefaultRequest() { } bool Http2Client::DoRstAfterHeader() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header"); + VLOG(2) << "Sending RPC and expecting reset stream after header"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); CHECK(!response.has_payload()); // no data should be received - gpr_log(GPR_DEBUG, "Done testing reset stream after header"); + VLOG(2) << "Done testing reset stream after header"; return true; } bool Http2Client::DoRstAfterData() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data"); + VLOG(2) << "Sending RPC and expecting reset stream after data"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); // There is no guarantee that data would be received. - gpr_log(GPR_DEBUG, "Done testing reset stream after data"); + VLOG(2) << "Done testing reset stream after data"; return true; } bool Http2Client::DoRstDuringData() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data"); + VLOG(2) << "Sending RPC and expecting reset stream during data"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); CHECK(!response.has_payload()); // no data should be received - gpr_log(GPR_DEBUG, "Done testing reset stream during data"); + VLOG(2) << "Done testing reset stream during data"; return true; } bool Http2Client::DoGoaway() { - gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway"); + VLOG(2) << "Sending two RPCs and expecting goaway"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0')); @@ -127,16 +127,16 @@ bool Http2Client::DoGoaway() { response.Clear(); AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0')); - gpr_log(GPR_DEBUG, "Done testing goaway"); + VLOG(2) << "Done testing goaway"; return true; } bool Http2Client::DoPing() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting ping"); + VLOG(2) << "Sending RPC and expecting ping"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0')); - gpr_log(GPR_DEBUG, "Done testing ping"); + VLOG(2) << "Done testing ping"; return true; } @@ -148,7 +148,7 @@ void Http2Client::MaxStreamsWorker( } bool Http2Client::DoMaxStreams() { - gpr_log(GPR_DEBUG, "Testing max streams"); + VLOG(2) << "Testing max streams"; // Make an initial call on the channel to ensure the server's max streams // setting is received @@ -167,7 +167,7 @@ bool Http2Client::DoMaxStreams() { it->join(); } - gpr_log(GPR_DEBUG, "Done testing max streams"); + VLOG(2) << "Done testing max streams"; return true; } @@ -198,7 +198,7 @@ int main(int argc, char** argv) { CHECK(channel->WaitForConnected(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN)))); grpc::testing::Http2Client client(channel); - gpr_log(GPR_INFO, "Testing case: %s", absl::GetFlag(FLAGS_test_case).c_str()); + LOG(INFO) << "Testing case: " << absl::GetFlag(FLAGS_test_case); int ret = 0; if (absl::GetFlag(FLAGS_test_case) == "rst_after_header") { client.DoRstAfterHeader(); @@ -219,8 +219,9 @@ int main(int argc, char** argv) { char* joined_testcases = gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", nullptr); - gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s", - absl::GetFlag(FLAGS_test_case).c_str(), joined_testcases); + LOG(ERROR) << "Unsupported test case " << absl::GetFlag(FLAGS_test_case) + << ". Valid options are\n" + << joined_testcases; gpr_free(joined_testcases); ret = 1; } From f97fc0cb9912d23f97741d34d71eeebf7bf6444e Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap Date: Fri, 10 May 2024 02:00:41 -0700 Subject: [PATCH 17/33] [grpc][Gpr_To_Absl_Logging] Removing old gpr logging code PiperOrigin-RevId: 632422235 --- src/core/lib/gpr/android/log.cc | 19 -------------- src/core/lib/gpr/linux/log.cc | 45 --------------------------------- src/core/lib/gpr/log.cc | 11 -------- src/core/lib/gpr/posix/log.cc | 42 ------------------------------ src/core/lib/gpr/windows/log.cc | 43 ------------------------------- 5 files changed, 160 deletions(-) diff --git a/src/core/lib/gpr/android/log.cc b/src/core/lib/gpr/android/log.cc index 34c705b8764..c368f3aa324 100644 --- a/src/core/lib/gpr/android/log.cc +++ b/src/core/lib/gpr/android/log.cc @@ -57,23 +57,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, free(message); } -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char* output = NULL; - - final_slash = strrchr(args->file, '/'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - asprintf(&output, "%s:%d] %s", display_file, args->line, args->message); - - __android_log_write(severity_to_log_priority(args->severity), "GRPC", output); - - // allocated by asprintf => use free, not gpr_free - free(output); -} - #endif // GPR_ANDROID diff --git a/src/core/lib/gpr/linux/log.cc b/src/core/lib/gpr/linux/log.cc index a24e28fa82c..f09ecb2dbbc 100644 --- a/src/core/lib/gpr/linux/log.cc +++ b/src/core/lib/gpr/linux/log.cc @@ -47,10 +47,6 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/examine_stack.h" -int gpr_should_log_stacktrace(gpr_log_severity severity); - -static long sys_gettid(void) { return syscall(__NR_gettid); } - void gpr_log(const char* file, int line, gpr_log_severity severity, const char* format, ...) { // Avoid message construction if gpr_log_message won't log @@ -70,45 +66,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, free(message); } -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - static thread_local long tid(0); - if (tid == 0) tid = sys_gettid(); - - timer = static_cast(now.tv_sec); - final_slash = strrchr(args->file, '/'); - if (final_slash == nullptr) { - display_file = args->file; - } else { - display_file = final_slash + 1; - } - - if (!localtime_r(&timer, &tm)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - std::string prefix = absl::StrFormat( - "%s%s.%09" PRId32 " %7ld %s:%d]", gpr_log_severity_string(args->severity), - time_buffer, now.tv_nsec, tid, display_file, args->line); - - absl::optional stack_trace = - gpr_should_log_stacktrace(args->severity) - ? grpc_core::GetCurrentStackTrace() - : absl::nullopt; - if (stack_trace) { - fprintf(stderr, "%-70s %s\n%s\n", prefix.c_str(), args->message, - stack_trace->c_str()); - } else { - fprintf(stderr, "%-70s %s\n", prefix.c_str(), args->message); - } -} - #endif // GPR_LINUX_LOG diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc index 1755d99122d..f1cd2938137 100644 --- a/src/core/lib/gpr/log.cc +++ b/src/core/lib/gpr/log.cc @@ -77,10 +77,6 @@ int gpr_should_log(gpr_log_severity severity) { } void gpr_default_log(gpr_log_func_args* args) { - if (!grpc_core::ConfigVars::Get().AbslLogging()) { - gpr_platform_log(args); - return; - } switch (args->severity) { case GPR_LOG_SEVERITY_DEBUG: // Log DEBUG messages as VLOG(2). @@ -99,13 +95,6 @@ void gpr_default_log(gpr_log_func_args* args) { } } -int gpr_should_log_stacktrace(gpr_log_severity severity) { - return static_cast(severity) >= - gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace) - ? 1 - : 0; -} - void gpr_log_message(const char* file, int line, gpr_log_severity severity, const char* message) { if (gpr_should_log(severity) == 0) { diff --git a/src/core/lib/gpr/posix/log.cc b/src/core/lib/gpr/posix/log.cc index 4e933b7c4be..09791014ef8 100644 --- a/src/core/lib/gpr/posix/log.cc +++ b/src/core/lib/gpr/posix/log.cc @@ -38,10 +38,6 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/examine_stack.h" -int gpr_should_log_stacktrace(gpr_log_severity severity); - -static intptr_t sys_gettid(void) { return (intptr_t)pthread_self(); } - void gpr_log(const char* file, int line, gpr_log_severity severity, const char* format, ...) { // Avoid message construction if gpr_log_message won't log @@ -70,42 +66,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, gpr_free(allocated); } -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '/'); - if (final_slash == nullptr) - display_file = args->file; - else - display_file = final_slash + 1; - - if (!localtime_r(&timer, &tm)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - std::string prefix = absl::StrFormat( - "%s%s.%09d %7" PRIdPTR " %s:%d]", gpr_log_severity_string(args->severity), - time_buffer, (int)(now.tv_nsec), sys_gettid(), display_file, args->line); - - absl::optional stack_trace = - gpr_should_log_stacktrace(args->severity) - ? grpc_core::GetCurrentStackTrace() - : absl::nullopt; - if (stack_trace) { - fprintf(stderr, "%-70s %s\n%s\n", prefix.c_str(), args->message, - stack_trace->c_str()); - } else { - fprintf(stderr, "%-70s %s\n", prefix.c_str(), args->message); - } -} - #endif // defined(GPR_POSIX_LOG) diff --git a/src/core/lib/gpr/windows/log.cc b/src/core/lib/gpr/windows/log.cc index 4dc48698140..e4f2d14f008 100644 --- a/src/core/lib/gpr/windows/log.cc +++ b/src/core/lib/gpr/windows/log.cc @@ -33,8 +33,6 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/examine_stack.h" -int gpr_should_log_stacktrace(gpr_log_severity severity); - void gpr_log(const char* file, int line, gpr_log_severity severity, const char* format, ...) { // Avoid message construction if gpr_log_message won't log @@ -72,45 +70,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, gpr_free(message); } -// Simple starter implementation -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '\\'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - if (localtime_s(&tm, &timer)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - absl::optional stack_trace = - gpr_should_log_stacktrace(args->severity) - ? grpc_core::GetCurrentStackTrace() - : absl::nullopt; - if (stack_trace) { - fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n%s\n", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line, - args->message, stack_trace->c_str()); - } else { - fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line, - args->message); - } - fflush(stderr); -} - #endif // GPR_WINDOWS_LOG From 4fac69ee2a4f68a5dd7f67bad551c69ff2b62058 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Fri, 10 May 2024 02:39:03 -0700 Subject: [PATCH 18/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36579) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36579 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36579 from tanvi-jagtap:actual_all_build_changes_tjagtap 49b69025c3d2ee501fb4a42fb0c81e2097bf21c9 PiperOrigin-RevId: 632430880 --- BUILD | 9 +++++++++ src/core/BUILD | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/BUILD b/BUILD index 55bb4f4a347..90980a7a952 100644 --- a/BUILD +++ b/BUILD @@ -1136,6 +1136,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/memory", "absl/meta:type_traits", "absl/status", @@ -1645,6 +1646,7 @@ grpc_cc_library( "absl/container:flat_hash_set", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2015,6 +2017,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/status", "absl/status:statusor", @@ -3672,6 +3675,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3995,6 +3999,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4087,6 +4092,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "@com_google_protobuf//upb:base", "@com_google_protobuf//upb:mem", @@ -4209,6 +4215,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4342,6 +4349,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/memory", "absl/status", "absl/status:statusor", @@ -4719,6 +4727,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/hash", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/random:bit_gen_ref", diff --git a/src/core/BUILD b/src/core/BUILD index ddb7e1d6669..87225db6d7c 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -754,6 +754,7 @@ grpc_cc_library( name = "join_state", external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", public_hdrs = [ @@ -843,6 +844,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -4825,6 +4827,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4942,6 +4945,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/hash", "absl/log:check", + "absl/log:log", "absl/random", "absl/status", "absl/status:statusor", @@ -5644,6 +5648,7 @@ grpc_cc_library( external_deps = [ "absl/algorithm:container", "absl/log:check", + "absl/log:log", "absl/random", "absl/status", "absl/status:statusor", @@ -5868,6 +5873,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -5938,6 +5944,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -6084,6 +6091,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", From 863029b7fe2a4971312c29a98a93f0861eb81176 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Fri, 10 May 2024 03:29:32 -0700 Subject: [PATCH 19/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36577) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36577 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36577 from tanvi-jagtap:test_core_all 9887d74d81ceffcedf8c9712056763e822db7b35 PiperOrigin-RevId: 632441576 --- test/core/address_utils/BUILD | 6 +++++- test/core/address_utils/parse_address_test.cc | 14 +++++++------- .../parse_address_with_named_scope_id_test.cc | 13 +++++-------- test/core/bad_client/bad_client.cc | 15 +++++++-------- test/core/bad_client/generate_tests.bzl | 7 ++++--- test/core/bad_connection/BUILD | 5 ++++- test/core/bad_connection/close_fd_test.cc | 14 +++++++------- test/core/bad_ssl/generate_tests.bzl | 1 + test/core/bad_ssl/server_common.cc | 4 ++-- test/core/channel/BUILD | 2 ++ test/core/channel/channel_args_test.cc | 6 +++--- test/core/channel/metrics_test.cc | 13 +++++++------ test/core/compression/BUILD | 10 ++++++++-- test/core/compression/compression_test.cc | 10 +++++----- test/core/compression/message_compress_test.cc | 1 - 15 files changed, 67 insertions(+), 54 deletions(-) diff --git a/test/core/address_utils/BUILD b/test/core/address_utils/BUILD index 15f41c3f9d5..ceb5a12dbb6 100644 --- a/test/core/address_utils/BUILD +++ b/test/core/address_utils/BUILD @@ -41,6 +41,7 @@ grpc_cc_test( name = "parse_address_test", srcs = ["parse_address_test.cc"], external_deps = [ + "absl/log:log", "absl/strings", "gtest", ], @@ -69,7 +70,10 @@ grpc_fuzzer( grpc_cc_test( name = "parse_address_with_named_scope_id_test", srcs = ["parse_address_with_named_scope_id_test.cc"], - external_deps = ["gtest"], + external_deps = [ + "absl/log:log", + "gtest", + ], language = "C++", tags = ["no_windows"], uses_event_engine = False, diff --git a/test/core/address_utils/parse_address_test.cc b/test/core/address_utils/parse_address_test.cc index d94370556e5..41b9df4bd5d 100644 --- a/test/core/address_utils/parse_address_test.cc +++ b/test/core/address_utils/parse_address_test.cc @@ -34,12 +34,12 @@ #include +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/strings/match.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/port.h" @@ -53,7 +53,7 @@ static void test_grpc_parse_unix(const char* uri_text, const char* pathname) { grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -70,7 +70,7 @@ static void test_grpc_parse_unix_abstract(const char* uri_text, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -98,7 +98,7 @@ static void test_grpc_parse_vsock(const char* uri_text, uint32_t cid, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -122,7 +122,7 @@ static void test_grpc_parse_ipv4(const char* uri_text, const char* host, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -142,7 +142,7 @@ static void test_grpc_parse_ipv6(const char* uri_text, const char* host, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -162,7 +162,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) { grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; diff --git a/test/core/address_utils/parse_address_with_named_scope_id_test.cc b/test/core/address_utils/parse_address_with_named_scope_id_test.cc index a69fa0072b8..eb76adef43d 100644 --- a/test/core/address_utils/parse_address_with_named_scope_id_test.cc +++ b/test/core/address_utils/parse_address_with_named_scope_id_test.cc @@ -28,13 +28,13 @@ #include +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/gprpp/crash.h" @@ -114,10 +114,8 @@ TEST(ParseAddressWithNamedScopeIdTest, MainTest) { // system recognizes, and then use that for the test. for (size_t i = 1; i < 65536; i++) { if (if_indextoname(i, arbitrary_interface_name) != nullptr) { - gpr_log(GPR_DEBUG, - "Found interface at index %" PRIuPTR - " named %s. Will use this for the test", - i, arbitrary_interface_name); + VLOG(2) << "Found interface at index " << i << " named " + << arbitrary_interface_name << ". Will use this for the test"; break; } } @@ -127,9 +125,8 @@ TEST(ParseAddressWithNamedScopeIdTest, MainTest) { struct sockaddr_in6 result_from_getaddrinfo = resolve_with_gettaddrinfo(target.c_str()); // Run the test - gpr_log(GPR_DEBUG, - "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: %s", - target.c_str()); + VLOG(2) << "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: " + << target; test_grpc_parse_ipv6_parity_with_getaddrinfo(target.c_str(), result_from_getaddrinfo); // Cleanup diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index ee7e1ee4d39..f11000ead0f 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -22,11 +22,11 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include #include -#include #include #include @@ -111,11 +111,11 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, hex = gpr_dump(arg->client_payload, arg->client_payload_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); // Add a debug log - gpr_log(GPR_INFO, "TEST: %s", hex); + LOG(INFO) << "TEST: " << hex; gpr_free(hex); } else { - gpr_log(GPR_INFO, "TEST: (%" PRIdPTR " byte long string)", - arg->client_payload_length); + LOG(INFO) << "TEST: (" << arg->client_payload_length + << " byte long string)"; } grpc_slice slice = grpc_slice_from_copied_buffer(arg->client_payload, @@ -171,9 +171,8 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, .type == GRPC_QUEUE_TIMEOUT); } while (!gpr_event_get(&read_done_event)); if (arg->client_validator(&incoming, arg->client_validator_arg)) break; - gpr_log(GPR_INFO, - "client validator failed; trying additional read " - "in case we didn't get all the data"); + LOG(INFO) << "client validator failed; trying additional read " + "in case we didn't get all the data"; } grpc_slice_buffer_destroy(&incoming); } @@ -317,7 +316,7 @@ bool rst_stream_client_validator(grpc_slice_buffer* incoming, void* /*arg*/) { *p++ == 0 || *p++ == 0 || *p++ == 0 || *p == 0 || *p == 11; if (!success) { - gpr_log(GPR_INFO, "client expected RST_STREAM frame, not found"); + LOG(INFO) << "client expected RST_STREAM frame, not found"; } grpc_slice_buffer_destroy(&last_frame_buffer); diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 620fb5a114e..2ae6c1b3c42 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -44,6 +44,10 @@ def grpc_bad_client_tests(): hdrs = ["bad_client.h"], language = "C++", testonly = 1, + external_deps = [ + "absl/log:check", + "absl/log:log", + ], deps = [ "//test/core/test_util:grpc_test_util", "//:grpc", @@ -51,9 +55,6 @@ def grpc_bad_client_tests(): "//test/core/end2end:cq_verifier", "//:grpc_http_filters", ], - external_deps = [ - "absl/log:check", - ], ) for t, topt in BAD_CLIENT_TESTS.items(): grpc_cc_test( diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD index d424ba888ac..5c674673037 100644 --- a/test/core/bad_connection/BUILD +++ b/test/core/bad_connection/BUILD @@ -23,7 +23,10 @@ grpc_cc_binary( srcs = [ "close_fd_test.cc", ], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", tags = ["no_windows"], deps = [ diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index a51f141270e..d3d69c8c068 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" @@ -53,7 +54,6 @@ #include #include #include -#include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/gprpp/crash.h" @@ -225,8 +225,8 @@ static void _test_close_before_server_recv(fd_type fdtype) { grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer* response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_recv", - fd_type_str(fdtype)); + LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype) + << "_before_server_recv"; test_init(); grpc_op ops[6]; @@ -399,8 +399,8 @@ static void _test_close_before_server_send(fd_type fdtype) { grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer* response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_send", - fd_type_str(fdtype)); + LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype) + << "_before_server_send"; test_init(); grpc_op ops[6]; @@ -596,8 +596,8 @@ static void _test_close_before_client_send(fd_type fdtype) { grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer* response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - gpr_log(GPR_INFO, "Running test: test_close_%s_before_client_send", - fd_type_str(fdtype)); + LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype) + << "_before_client_send"; test_init(); grpc_op ops[6]; diff --git a/test/core/bad_ssl/generate_tests.bzl b/test/core/bad_ssl/generate_tests.bzl index 3ce7de49171..ddd3b3c97bf 100755 --- a/test/core/bad_ssl/generate_tests.bzl +++ b/test/core/bad_ssl/generate_tests.bzl @@ -35,6 +35,7 @@ def grpc_bad_ssl_tests(): hdrs = ["server_common.h"], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "//test/core/test_util:grpc_test_util", diff --git a/test/core/bad_ssl/server_common.cc b/test/core/bad_ssl/server_common.cc index 1f9c0a69f5f..e76708b1969 100644 --- a/test/core/bad_ssl/server_common.cc +++ b/test/core/bad_ssl/server_common.cc @@ -21,8 +21,8 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" -#include #include #include "test/core/test_util/cmdline.h" @@ -74,7 +74,7 @@ void bad_ssl_run(grpc_server* server) { signal(SIGINT, sigint_handler); while (!shutdown_finished) { if (got_sigint && !shutdown_started) { - gpr_log(GPR_INFO, "Shutting down due to SIGINT"); + LOG(INFO) << "Shutting down due to SIGINT"; shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server_shutdown_and_notify(server, shutdown_cq, nullptr); CHECK(grpc_completion_queue_pluck(shutdown_cq, nullptr, diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index 10831f5090c..b54cc023fa3 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -37,6 +37,7 @@ grpc_cc_test( srcs = ["channel_args_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], language = "C++", @@ -149,6 +150,7 @@ grpc_cc_test( name = "metrics_test", srcs = ["metrics_test.cc"], external_deps = [ + "absl/log:log", "gtest", ], language = "C++", diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc index 3e59d01bfa0..1fe9f0937b1 100644 --- a/test/core/channel/channel_args_test.cc +++ b/test/core/channel/channel_args_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "gtest/gtest.h" #include @@ -28,7 +29,6 @@ #include #include #include -#include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/notification.h" @@ -272,7 +272,7 @@ struct fake_class { }; static void* fake_pointer_arg_copy(void* arg) { - gpr_log(GPR_DEBUG, "fake_pointer_arg_copy"); + VLOG(2) << "fake_pointer_arg_copy"; fake_class* fc = static_cast(arg); fake_class* new_fc = static_cast(gpr_malloc(sizeof(fake_class))); new_fc->foo = fc->foo; @@ -280,7 +280,7 @@ static void* fake_pointer_arg_copy(void* arg) { } static void fake_pointer_arg_destroy(void* arg) { - gpr_log(GPR_DEBUG, "fake_pointer_arg_destroy"); + VLOG(2) << "fake_pointer_arg_destroy"; fake_class* fc = static_cast(arg); gpr_free(fc); } diff --git a/test/core/channel/metrics_test.cc b/test/core/channel/metrics_test.cc index 20b915c7904..3d57b32d2ab 100644 --- a/test/core/channel/metrics_test.cc +++ b/test/core/channel/metrics_test.cc @@ -16,6 +16,7 @@ #include +#include "absl/log/log.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -217,7 +218,7 @@ TEST_F(MetricsTest, Int64CallbackGauge) { auto plugin3 = MakeStatsPluginForTarget(kDomain1To4); // Register two callbacks that set the same metric but with different // label values. The callbacks get used only by plugin1. - gpr_log(GPR_INFO, "testing callbacks for: plugin1"); + LOG(INFO) << "testing callbacks for: plugin1"; auto group1 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")); auto callback1 = group1.RegisterCallback( @@ -278,7 +279,7 @@ TEST_F(MetricsTest, Int64CallbackGauge) { callback1.reset(); callback2.reset(); // Now register callbacks that hit both plugin1 and plugin2. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2"; auto group2 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")); callback1 = group2.RegisterCallback( @@ -339,7 +340,7 @@ TEST_F(MetricsTest, Int64CallbackGauge) { callback1.reset(); callback2.reset(); // Now register callbacks that hit all three plugins. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2, plugin3"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2, plugin3"; auto group3 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")); callback1 = group3.RegisterCallback( @@ -422,7 +423,7 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { auto plugin3 = MakeStatsPluginForTarget(kDomain1To4); // Register two callbacks that set the same metric but with different // label values. The callbacks get used only by plugin1. - gpr_log(GPR_INFO, "testing callbacks for: plugin1"); + LOG(INFO) << "testing callbacks for: plugin1"; auto group1 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")); auto callback1 = group1.RegisterCallback( @@ -483,7 +484,7 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { callback1.reset(); callback2.reset(); // Now register callbacks that hit both plugin1 and plugin2. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2"; auto group2 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")); callback1 = group2.RegisterCallback( @@ -544,7 +545,7 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { callback1.reset(); callback2.reset(); // Now register callbacks that hit all three plugins. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2, plugin3"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2, plugin3"; auto group3 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")); callback1 = group3.RegisterCallback( diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index d6825f63e41..21746ffd776 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -26,7 +26,10 @@ licenses(["notice"]) grpc_cc_test( name = "compression_test", srcs = ["compression_test.cc"], - external_deps = ["gtest"], + external_deps = [ + "absl/log:log", + "gtest", + ], language = "C++", uses_event_engine = False, uses_polling = False, @@ -67,7 +70,10 @@ grpc_fuzzer( grpc_cc_test( name = "message_compress_test", srcs = ["message_compress_test.cc"], - external_deps = ["gtest"], + external_deps = [ + "absl/log:log", + "gtest", + ], language = "C++", uses_event_engine = False, uses_polling = False, diff --git a/test/core/compression/compression_test.cc b/test/core/compression/compression_test.cc index 2297e5c8303..569a1d7e2ff 100644 --- a/test/core/compression/compression_test.cc +++ b/test/core/compression/compression_test.cc @@ -21,11 +21,11 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include #include -#include #include "src/core/lib/gpr/useful.h" #include "test/core/test_util/test_config.h" @@ -40,7 +40,7 @@ TEST(CompressionTest, CompressionAlgorithmParse) { }; const char* invalid_names[] = {"gzip2", "foo", "", "2gzip"}; - gpr_log(GPR_DEBUG, "test_compression_algorithm_parse"); + VLOG(2) << "test_compression_algorithm_parse"; for (i = 0; i < GPR_ARRAY_SIZE(valid_names); i++) { const char* valid_name = valid_names[i]; @@ -73,7 +73,7 @@ TEST(CompressionTest, CompressionAlgorithmName) { GRPC_COMPRESS_DEFLATE, }; - gpr_log(GPR_DEBUG, "test_compression_algorithm_name"); + VLOG(2) << "test_compression_algorithm_name"; for (i = 0; i < GPR_ARRAY_SIZE(valid_algorithms); i++) { success = grpc_compression_algorithm_name(valid_algorithms[i], &name); @@ -88,7 +88,7 @@ TEST(CompressionTest, CompressionAlgorithmName) { } TEST(CompressionTest, CompressionAlgorithmForLevel) { - gpr_log(GPR_DEBUG, "test_compression_algorithm_for_level"); + VLOG(2) << "test_compression_algorithm_for_level"; { // accept only identity (aka none) @@ -211,7 +211,7 @@ TEST(CompressionTest, CompressionEnableDisableAlgorithm) { grpc_compression_options options; grpc_compression_algorithm algorithm; - gpr_log(GPR_DEBUG, "test_compression_enable_disable_algorithm"); + VLOG(2) << "test_compression_enable_disable_algorithm"; grpc_compression_options_init(&options); for (algorithm = GRPC_COMPRESS_NONE; diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc index b3cf8ba7e47..5666ed3e477 100644 --- a/test/core/compression/message_compress_test.cc +++ b/test/core/compression/message_compress_test.cc @@ -28,7 +28,6 @@ #include #include -#include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" From 1bfca77696ece88338768d4147cf10a83d94918d Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Fri, 10 May 2024 04:53:18 -0700 Subject: [PATCH 20/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36578) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36578 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36578 from tanvi-jagtap:all_build_changes_tjagtap bba460331a4461cfb8b19451ef2689ef84814b77 PiperOrigin-RevId: 632458570 --- BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD b/BUILD index 90980a7a952..7a295c7991b 100644 --- a/BUILD +++ b/BUILD @@ -2697,6 +2697,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/strings", ], language = "c++", From 57b7e7780e28f5540dcc82cb20f4268d3dbd5d06 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap Date: Fri, 10 May 2024 05:15:53 -0700 Subject: [PATCH 21/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging GPR_ASSERT Replaced GPR_DEBUG_ASSERT with absl DCHECK. We dont need GPR_DEBUG_ASSERT definition anymore. PiperOrigin-RevId: 632463102 --- include/grpc/support/log.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h index 6e5cf4b7157..2cba30164ff 100644 --- a/include/grpc/support/log.h +++ b/include/grpc/support/log.h @@ -99,12 +99,6 @@ GPRAPI void gpr_assertion_failed(const char* filename, int line, } \ } while (0) -#ifndef NDEBUG -#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(x) -#else -#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(true || (x)) -#endif - #ifdef __cplusplus } #endif From 3e412b4af180e08fce27afd759c3133b2a4fefb4 Mon Sep 17 00:00:00 2001 From: Gregory Cooke Date: Fri, 10 May 2024 12:37:37 -0700 Subject: [PATCH 22/33] [security] Add notices for functions we will be removing (#36488) Mark the following APIs in `TlsCredentialsOptions` as deprecated: `set_check_call_host`, `set_send_client_ca_list`, `set_crl_directory`. These APIs will be removed in release 1.66. Closes #36488 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36488 from gtcooke94:AddDeprecationNotes df8e4346432b68a46e504f5eeb3527e2a9cae575 PiperOrigin-RevId: 632574716 --- include/grpcpp/security/tls_credentials_options.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index 6adf9faac64..11c40f04086 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -103,6 +103,8 @@ class TlsCredentialsOptions { // call is covered by the cert that the peer presented. // We will perform such checks by default. This should be disabled if // verifiers other than the host name verifier is used. + // Deprecated: This function will be removed in the 1.66 release. This will be + // replaced by and handled within the custom verifier settings. void set_check_call_host(bool check_call_host); // Deprecated in favor of set_crl_provider. The @@ -111,6 +113,8 @@ class TlsCredentialsOptions { // If set, gRPC will read all hashed x.509 CRL files in the directory and // enforce the CRL files on all TLS handshakes. Only supported for OpenSSL // version > 1.1. + // Deprecated: This function will be removed in the 1.66 release. Use the + // set_crl_provider function instead. void set_crl_directory(const std::string& path); void set_crl_provider(std::shared_ptr crl_provider); @@ -184,6 +188,7 @@ class TlsServerCredentialsOptions final : public TlsCredentialsOptions { // WARNING: This API is extremely dangerous and should not be used. If the // server's trust bundle is too large, then the TLS server will be unable to // form a ServerHello, and hence will be unusable. + // Deprecated: This function will be removed in the 1.66 release. void set_send_client_ca_list(bool send_client_ca_list); private: From 88a75b3914649dad615a9c012c46976b8e6915b2 Mon Sep 17 00:00:00 2001 From: Luwei Ge Date: Fri, 10 May 2024 12:55:59 -0700 Subject: [PATCH 23/33] [test] Refactor the ssl transport security test (#36574) Closes #36574 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36574 from rockspore:ssl_test ae97bab2aacad87cb7898b579476691e7a2b8e54 PiperOrigin-RevId: 632579292 --- test/core/tsi/BUILD | 2 +- test/core/tsi/ssl_transport_security_test.cc | 1496 +++++++++--------- 2 files changed, 747 insertions(+), 751 deletions(-) diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD index ac8204ced28..f139e18b655 100644 --- a/test/core/tsi/BUILD +++ b/test/core/tsi/BUILD @@ -91,7 +91,7 @@ grpc_cc_test( grpc_cc_test( name = "ssl_transport_security_test", - timeout = "long", + timeout = "eternal", srcs = ["ssl_transport_security_test.cc"], data = [ "//src/core/tsi/test_creds:badclient.key", diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 0e6a5aa162a..ff1e0dcfa58 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -34,9 +34,7 @@ #include #include -#include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" #include "test/core/test_util/build.h" @@ -63,10 +61,6 @@ const size_t kSessionTicketEncryptionKeySize = 80; const size_t kSessionTicketEncryptionKeySize = 48; #endif -// Indicates the TLS version used for the test. -static tsi_tls_version test_tls_version = tsi_tls_version::TSI_TLS1_3; -static bool test_send_client_ca_list = false; - typedef enum AlpnMode { NO_ALPN, ALPN_CLIENT_NO_SERVER, @@ -102,215 +96,9 @@ typedef struct ssl_key_cert_lib { uint16_t leaf_signed_by_intermediate_num_key_cert_pairs; } ssl_key_cert_lib; -typedef struct ssl_tsi_test_fixture { - tsi_test_fixture base; - ssl_key_cert_lib* key_cert_lib; - ssl_alpn_lib* alpn_lib; - bool force_client_auth; - char* server_name_indication; - tsi_ssl_session_cache* session_cache; - bool session_reused; - const char* session_ticket_key; - size_t session_ticket_key_size; - size_t network_bio_buf_size; - size_t ssl_bio_buf_size; - bool verify_root_cert_subject; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; -} ssl_tsi_test_fixture; - -static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->key_cert_lib, nullptr); - ASSERT_NE(ssl_fixture->alpn_lib, nullptr); - ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - // Create client handshaker factory. - tsi_ssl_client_handshaker_options client_options; - if (key_cert_lib->use_pem_root_certs) { - client_options.pem_root_certs = key_cert_lib->root_cert; - } - if (ssl_fixture->force_client_auth) { - client_options.pem_key_cert_pair = - key_cert_lib->use_bad_client_cert - ? &key_cert_lib->bad_client_pem_key_cert_pair - : &key_cert_lib->client_pem_key_cert_pair; - } - if (alpn_lib->alpn_mode == ALPN_CLIENT_NO_SERVER || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - client_options.alpn_protocols = alpn_lib->client_alpn_protocols; - client_options.num_alpn_protocols = alpn_lib->num_client_alpn_protocols; - } - client_options.root_store = - key_cert_lib->use_root_store ? key_cert_lib->root_store : nullptr; - if (ssl_fixture->session_cache != nullptr) { - client_options.session_cache = ssl_fixture->session_cache; - } - client_options.min_tls_version = test_tls_version; - client_options.max_tls_version = test_tls_version; - client_options.skip_server_certificate_verification = - key_cert_lib->skip_server_certificate_verification; - ASSERT_EQ(tsi_create_ssl_client_handshaker_factory_with_options( - &client_options, &ssl_fixture->client_handshaker_factory), - TSI_OK); - // Create server handshaker factory. - tsi_ssl_server_handshaker_options server_options; - if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - server_options.alpn_protocols = alpn_lib->server_alpn_protocols; - server_options.num_alpn_protocols = alpn_lib->num_server_alpn_protocols; - if (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - server_options.num_alpn_protocols--; - } - } - if (key_cert_lib->use_cert_signed_by_intermediate_ca) { - server_options.pem_key_cert_pairs = - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs; - server_options.num_key_cert_pairs = - key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs; - } else { - server_options.pem_key_cert_pairs = - key_cert_lib->use_bad_server_cert - ? key_cert_lib->bad_server_pem_key_cert_pairs - : key_cert_lib->server_pem_key_cert_pairs; - server_options.num_key_cert_pairs = - key_cert_lib->use_bad_server_cert - ? key_cert_lib->bad_server_num_key_cert_pairs - : key_cert_lib->server_num_key_cert_pairs; - } - server_options.pem_client_root_certs = key_cert_lib->root_cert; - if (ssl_fixture->force_client_auth) { - server_options.client_certificate_request = - TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; - } else { - server_options.client_certificate_request = - TSI_DONT_REQUEST_CLIENT_CERTIFICATE; - } - server_options.send_client_ca_list = test_send_client_ca_list; - server_options.session_ticket_key = ssl_fixture->session_ticket_key; - server_options.session_ticket_key_size = ssl_fixture->session_ticket_key_size; - server_options.min_tls_version = test_tls_version; - server_options.max_tls_version = test_tls_version; - ASSERT_EQ(tsi_create_ssl_server_handshaker_factory_with_options( - &server_options, &ssl_fixture->server_handshaker_factory), - TSI_OK); - // Create server and client handshakers. - ASSERT_EQ( - tsi_ssl_client_handshaker_factory_create_handshaker( - ssl_fixture->client_handshaker_factory, - ssl_fixture->server_name_indication, - ssl_fixture->network_bio_buf_size, ssl_fixture->ssl_bio_buf_size, - &ssl_fixture->base.client_handshaker), - TSI_OK); - ASSERT_EQ( - tsi_ssl_server_handshaker_factory_create_handshaker( - ssl_fixture->server_handshaker_factory, - ssl_fixture->network_bio_buf_size, ssl_fixture->ssl_bio_buf_size, - &ssl_fixture->base.server_handshaker), - TSI_OK); -} - -static void check_verified_root_cert_subject( - ssl_tsi_test_fixture* /*ssl_fixture*/, const tsi_peer* peer) { - const tsi_peer_property* verified_root_cert_subject = - tsi_peer_get_property_by_name( - peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); - ASSERT_NE(verified_root_cert_subject, nullptr); - const char* expected_match = - "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; - ASSERT_EQ(memcmp(verified_root_cert_subject->value.data, expected_match, - verified_root_cert_subject->value.length), - 0); -} - -static void check_verified_root_cert_subject_unset( - ssl_tsi_test_fixture* /*ssl_fixture*/, const tsi_peer* peer) { - const tsi_peer_property* verified_root_cert_subject = - tsi_peer_get_property_by_name( - peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); - ASSERT_EQ(verified_root_cert_subject, nullptr); -} - -static void check_alpn(ssl_tsi_test_fixture* ssl_fixture, - const tsi_peer* peer) { - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->alpn_lib, nullptr); - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - const tsi_peer_property* alpn_property = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (alpn_lib->alpn_mode != ALPN_CLIENT_SERVER_OK) { - ASSERT_EQ(alpn_property, nullptr); - } else { - ASSERT_NE(alpn_property, nullptr); - const char* expected_match = "baz"; - ASSERT_EQ(memcmp(alpn_property->value.data, expected_match, - alpn_property->value.length), - 0); - } -} - -static void check_security_level(const tsi_peer* peer) { - const tsi_peer_property* security_level = - tsi_peer_get_property_by_name(peer, TSI_SECURITY_LEVEL_PEER_PROPERTY); - ASSERT_NE(security_level, nullptr); - const char* expected_match = "TSI_PRIVACY_AND_INTEGRITY"; - ASSERT_EQ(memcmp(security_level->value.data, expected_match, - security_level->value.length), - 0); -} - -static const tsi_peer_property* -check_basic_authenticated_peer_and_get_common_name(const tsi_peer* peer) { - const tsi_peer_property* cert_type_property = - tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); - EXPECT_NE(cert_type_property, nullptr); - EXPECT_EQ(memcmp(cert_type_property->value.data, TSI_X509_CERTIFICATE_TYPE, - cert_type_property->value.length), - 0); - const tsi_peer_property* property = tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - EXPECT_NE(property, nullptr); - return property; -} - -static void check_session_reusage(ssl_tsi_test_fixture* ssl_fixture, - tsi_peer* peer) { - const tsi_peer_property* session_reused = - tsi_peer_get_property_by_name(peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY); - ASSERT_NE(session_reused, nullptr); - if (ssl_fixture->session_reused) { - ASSERT_EQ(strncmp(session_reused->value.data, "true", - session_reused->value.length), - 0); - } else { - ASSERT_EQ(strncmp(session_reused->value.data, "false", - session_reused->value.length), - 0); - } -} - -void check_server0_peer(tsi_peer* peer) { - const tsi_peer_property* property = - check_basic_authenticated_peer_and_get_common_name(peer); - const char* expected_match = "*.test.google.com.au"; - ASSERT_EQ( - memcmp(property->value.data, expected_match, property->value.length), 0); - ASSERT_EQ(tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY), - nullptr); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "BAR.TEST.GOOGLE.COM.AU"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "Bar.Test.Google.Com.Au"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bAr.TeST.gOOgle.cOm.AU"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.com.au"), 0); - tsi_peer_destruct(peer); +static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) { + gpr_free(const_cast(kp.private_key)); + gpr_free(const_cast(kp.cert_chain)); } static bool check_property(tsi_peer* peer, const char* property_name, @@ -327,183 +115,6 @@ static bool check_property(tsi_peer* peer, const char* property_name, return false; } -void check_server1_peer(tsi_peer* peer) { - const tsi_peer_property* property = - check_basic_authenticated_peer_and_get_common_name(peer); - const char* expected_match = "*.test.google.com"; - ASSERT_EQ( - memcmp(property->value.data, expected_match, property->value.length), 0); - ASSERT_EQ( - check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - "*.test.google.fr"), - 1); - ASSERT_EQ( - check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - "waterzooi.test.google.be"), - 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.fr"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.fr"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"), 0); - tsi_peer_destruct(peer); -} - -static void check_client_peer(ssl_tsi_test_fixture* ssl_fixture, - tsi_peer* peer) { - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->alpn_lib, nullptr); - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - if (!ssl_fixture->force_client_auth) { - ASSERT_EQ(peer->property_count, - (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 3 : 2)); - } else { - const tsi_peer_property* property = - check_basic_authenticated_peer_and_get_common_name(peer); - const char* expected_match = "testclient"; - ASSERT_EQ( - memcmp(property->value.data, expected_match, property->value.length), - 0); - } - tsi_peer_destruct(peer); -} - -static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->key_cert_lib, nullptr); - ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; - tsi_peer peer; - // In TLS 1.3, the client-side handshake succeeds even if the client sends a - // bad certificate. In such a case, the server would fail the TLS handshake - // and send an alert to the client as the first application data message. In - // TLS 1.2, the client-side handshake will fail if the client sends a bad - // certificate. - // - // For OpenSSL versions < 1.1, TLS 1.3 is not supported, so the client-side - // handshake should succeed precisely when the server-side handshake - // succeeds. - bool expect_server_success = - !(key_cert_lib->use_bad_server_cert || - (key_cert_lib->use_bad_client_cert && ssl_fixture->force_client_auth)); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - bool expect_client_success = test_tls_version == tsi_tls_version::TSI_TLS1_2 - ? expect_server_success - : !key_cert_lib->use_bad_server_cert; -#else - bool expect_client_success = expect_server_success; -#endif - if (expect_client_success) { - ASSERT_EQ(tsi_handshaker_result_extract_peer( - ssl_fixture->base.client_result, &peer), - TSI_OK); - check_session_reusage(ssl_fixture, &peer); - check_alpn(ssl_fixture, &peer); - check_security_level(&peer); - if (ssl_fixture->verify_root_cert_subject) { - if (!ssl_fixture->session_reused) { - check_verified_root_cert_subject(ssl_fixture, &peer); - } else { - check_verified_root_cert_subject_unset(ssl_fixture, &peer); - } - } - if (ssl_fixture->server_name_indication == nullptr || - strcmp(ssl_fixture->server_name_indication, SSL_TSI_TEST_WRONG_SNI) == - 0 || - strcmp(ssl_fixture->server_name_indication, SSL_TSI_TEST_INVALID_SNI) == - 0) { - // Expect server to use default server0.pem. - check_server0_peer(&peer); - } else { - // Expect server to use server1.pem. - check_server1_peer(&peer); - } - } else { - ASSERT_EQ(ssl_fixture->base.client_result, nullptr); - } - if (expect_server_success) { - ASSERT_EQ(tsi_handshaker_result_extract_peer( - ssl_fixture->base.server_result, &peer), - TSI_OK); - check_session_reusage(ssl_fixture, &peer); - check_alpn(ssl_fixture, &peer); - check_security_level(&peer); - if (ssl_fixture->force_client_auth && !ssl_fixture->session_reused) { - check_verified_root_cert_subject(ssl_fixture, &peer); - } else { - check_verified_root_cert_subject_unset(ssl_fixture, &peer); - } - check_client_peer(ssl_fixture, &peer); - } else { - ASSERT_EQ(ssl_fixture->base.server_result, nullptr); - } -} - -static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) { - gpr_free(const_cast(kp.private_key)); - gpr_free(const_cast(kp.cert_chain)); -} - -static void ssl_test_destruct(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - if (ssl_fixture == nullptr) { - return; - } - // Destroy ssl_alpn_lib. - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - for (size_t i = 0; i < alpn_lib->num_server_alpn_protocols; i++) { - gpr_free(const_cast(alpn_lib->server_alpn_protocols[i])); - } - gpr_free(alpn_lib->server_alpn_protocols); - for (size_t i = 0; i < alpn_lib->num_client_alpn_protocols; i++) { - gpr_free(const_cast(alpn_lib->client_alpn_protocols[i])); - } - gpr_free(alpn_lib->client_alpn_protocols); - gpr_free(alpn_lib); - // Destroy ssl_key_cert_lib. - ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; - for (size_t i = 0; i < key_cert_lib->server_num_key_cert_pairs; i++) { - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->server_pem_key_cert_pairs[i]); - } - gpr_free(key_cert_lib->server_pem_key_cert_pairs); - for (size_t i = 0; i < key_cert_lib->bad_server_num_key_cert_pairs; i++) { - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->bad_server_pem_key_cert_pairs[i]); - } - gpr_free(key_cert_lib->bad_server_pem_key_cert_pairs); - for (size_t i = 0; - i < key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs; i++) { - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs[i]); - } - gpr_free(key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs); - ssl_test_pem_key_cert_pair_destroy(key_cert_lib->client_pem_key_cert_pair); - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->bad_client_pem_key_cert_pair); - gpr_free(key_cert_lib->root_cert); - tsi_ssl_root_certs_store_destroy(key_cert_lib->root_store); - gpr_free(key_cert_lib); - if (ssl_fixture->session_cache != nullptr) { - tsi_ssl_session_cache_unref(ssl_fixture->session_cache); - } - // Unreference others. - tsi_ssl_server_handshaker_factory_unref( - ssl_fixture->server_handshaker_factory); - tsi_ssl_client_handshaker_factory_unref( - ssl_fixture->client_handshaker_factory); - gpr_free(ssl_fixture); -} - -static const struct tsi_test_fixture_vtable vtable = { - ssl_test_setup_handshakers, ssl_test_check_handshaker_peers, - ssl_test_destruct}; - static char* load_file(std::string path) { std::string data = grpc_core::testing::GetFileContents(path); return gpr_strdup(data.c_str()); @@ -535,310 +146,756 @@ static std::string GenerateTrustBundle() { return trust_bundle; } -static tsi_test_fixture* ssl_tsi_test_fixture_create() { - ssl_tsi_test_fixture* ssl_fixture = grpc_core::Zalloc(); - tsi_test_fixture_init(&ssl_fixture->base); - ssl_fixture->verify_root_cert_subject = true; - ssl_fixture->base.test_unused_bytes = true; - ssl_fixture->base.vtable = &vtable; - // Create ssl_key_cert_lib. - ssl_key_cert_lib* key_cert_lib = grpc_core::Zalloc(); - key_cert_lib->use_bad_server_cert = false; - key_cert_lib->use_bad_client_cert = false; - key_cert_lib->use_root_store = false; - key_cert_lib->use_pem_root_certs = true; - key_cert_lib->skip_server_certificate_verification = false; - key_cert_lib->server_num_key_cert_pairs = - SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM; - key_cert_lib->bad_server_num_key_cert_pairs = - SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM; - key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs = - SSL_TSI_TEST_LEAF_SIGNED_BY_INTERMEDIATE_KEY_CERT_PAIRS_NUM; - key_cert_lib->server_pem_key_cert_pairs = - static_cast( - gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * - key_cert_lib->server_num_key_cert_pairs)); - key_cert_lib->bad_server_pem_key_cert_pairs = - static_cast( - gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * - key_cert_lib->bad_server_num_key_cert_pairs)); - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs = - static_cast(gpr_malloc( - sizeof(tsi_ssl_pem_key_cert_pair) * - key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs)); - key_cert_lib->server_pem_key_cert_pairs[0].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.key"); - key_cert_lib->server_pem_key_cert_pairs[0].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.pem"); - key_cert_lib->server_pem_key_cert_pairs[1].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.key"); - key_cert_lib->server_pem_key_cert_pairs[1].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.pem"); - key_cert_lib->bad_server_pem_key_cert_pairs[0].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.key"); - key_cert_lib->bad_server_pem_key_cert_pairs[0].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.pem"); - key_cert_lib->client_pem_key_cert_pair.private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.key"); - key_cert_lib->client_pem_key_cert_pair.cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.pem"); - key_cert_lib->bad_client_pem_key_cert_pair.private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.key"); - key_cert_lib->bad_client_pem_key_cert_pair.cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.pem"); - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs[0].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "leaf_signed_by_intermediate.key"); - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs[0].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "leaf_and_intermediate_chain.pem"); - key_cert_lib->root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); - key_cert_lib->root_store = - tsi_ssl_root_certs_store_create(key_cert_lib->root_cert); - EXPECT_NE(key_cert_lib->root_store, nullptr); - ssl_fixture->key_cert_lib = key_cert_lib; - // Create ssl_alpn_lib. - ssl_alpn_lib* alpn_lib = grpc_core::Zalloc(); - alpn_lib->server_alpn_protocols = static_cast( - gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); - alpn_lib->client_alpn_protocols = static_cast( - gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); - alpn_lib->server_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN1); - alpn_lib->server_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); - alpn_lib->client_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN2); - alpn_lib->client_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); - alpn_lib->num_server_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; - alpn_lib->num_client_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; - alpn_lib->alpn_mode = NO_ALPN; - ssl_fixture->alpn_lib = alpn_lib; - ssl_fixture->base.vtable = &vtable; - ssl_fixture->server_name_indication = nullptr; - ssl_fixture->session_reused = false; - ssl_fixture->session_ticket_key = nullptr; - ssl_fixture->session_ticket_key_size = 0; - ssl_fixture->force_client_auth = false; - ssl_fixture->network_bio_buf_size = 0; - ssl_fixture->ssl_bio_buf_size = 0; - return &ssl_fixture->base; -} +class SslTransportSecurityTest + : public ::testing::TestWithParam> { + protected: + // A tsi_test_fixture implementation + class SslTsiTestFixture { + public: + SslTsiTestFixture(tsi_tls_version tls_version, bool send_client_ca_list) { + tsi_test_fixture_init(&base_); + verify_root_cert_subject_ = true; + base_.test_unused_bytes = true; + base_.vtable = &kVtable; + // Create ssl_key_cert_lib. + key_cert_lib_ = grpc_core::Zalloc(); + key_cert_lib_->use_bad_server_cert = false; + key_cert_lib_->use_bad_client_cert = false; + key_cert_lib_->use_root_store = false; + key_cert_lib_->use_pem_root_certs = true; + key_cert_lib_->skip_server_certificate_verification = false; + key_cert_lib_->server_num_key_cert_pairs = + SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM; + key_cert_lib_->bad_server_num_key_cert_pairs = + SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM; + key_cert_lib_->leaf_signed_by_intermediate_num_key_cert_pairs = + SSL_TSI_TEST_LEAF_SIGNED_BY_INTERMEDIATE_KEY_CERT_PAIRS_NUM; + key_cert_lib_->server_pem_key_cert_pairs = + static_cast( + gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * + key_cert_lib_->server_num_key_cert_pairs)); + key_cert_lib_->bad_server_pem_key_cert_pairs = + static_cast( + gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * + key_cert_lib_->bad_server_num_key_cert_pairs)); + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs = + static_cast(gpr_malloc( + sizeof(tsi_ssl_pem_key_cert_pair) * + key_cert_lib_->leaf_signed_by_intermediate_num_key_cert_pairs)); + key_cert_lib_->server_pem_key_cert_pairs[0].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.key"); + key_cert_lib_->server_pem_key_cert_pairs[0].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.pem"); + key_cert_lib_->server_pem_key_cert_pairs[1].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.key"); + key_cert_lib_->server_pem_key_cert_pairs[1].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.pem"); + key_cert_lib_->bad_server_pem_key_cert_pairs[0].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.key"); + key_cert_lib_->bad_server_pem_key_cert_pairs[0].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.pem"); + key_cert_lib_->client_pem_key_cert_pair.private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.key"); + key_cert_lib_->client_pem_key_cert_pair.cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.pem"); + key_cert_lib_->bad_client_pem_key_cert_pair.private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.key"); + key_cert_lib_->bad_client_pem_key_cert_pair.cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.pem"); + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs[0].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR + "leaf_signed_by_intermediate.key"); + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs[0].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR + "leaf_and_intermediate_chain.pem"); + key_cert_lib_->root_cert = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); + key_cert_lib_->root_store = + tsi_ssl_root_certs_store_create(key_cert_lib_->root_cert); + EXPECT_NE(key_cert_lib_->root_store, nullptr); + // Create ssl_alpn_lib. + alpn_lib_ = grpc_core::Zalloc(); + alpn_lib_->server_alpn_protocols = static_cast( + gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); + alpn_lib_->client_alpn_protocols = static_cast( + gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); + alpn_lib_->server_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN1); + alpn_lib_->server_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); + alpn_lib_->client_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN2); + alpn_lib_->client_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); + alpn_lib_->num_server_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; + alpn_lib_->num_client_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; + alpn_lib_->alpn_mode = NO_ALPN; + server_name_indication_ = nullptr; + session_reused_ = false; + session_ticket_key_ = nullptr; + session_ticket_key_size_ = 0; + force_client_auth_ = false; + network_bio_buf_size_ = 0; + ssl_bio_buf_size_ = 0; + send_client_ca_list_ = send_client_ca_list; + tls_version_ = tls_version; + } + + ~SslTsiTestFixture() { + // Destroy ssl_alpn_lib. + for (size_t i = 0; i < alpn_lib_->num_server_alpn_protocols; i++) { + gpr_free(const_cast(alpn_lib_->server_alpn_protocols[i])); + } + gpr_free(alpn_lib_->server_alpn_protocols); + for (size_t i = 0; i < alpn_lib_->num_client_alpn_protocols; i++) { + gpr_free(const_cast(alpn_lib_->client_alpn_protocols[i])); + } + gpr_free(alpn_lib_->client_alpn_protocols); + gpr_free(alpn_lib_); + // Destroy ssl_key_cert_lib. + for (size_t i = 0; i < key_cert_lib_->server_num_key_cert_pairs; i++) { + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->server_pem_key_cert_pairs[i]); + } + gpr_free(key_cert_lib_->server_pem_key_cert_pairs); + for (size_t i = 0; i < key_cert_lib_->bad_server_num_key_cert_pairs; + i++) { + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->bad_server_pem_key_cert_pairs[i]); + } + gpr_free(key_cert_lib_->bad_server_pem_key_cert_pairs); + for (size_t i = 0; + i < key_cert_lib_->leaf_signed_by_intermediate_num_key_cert_pairs; + i++) { + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs[i]); + } + gpr_free(key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs); + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->client_pem_key_cert_pair); + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->bad_client_pem_key_cert_pair); + gpr_free(key_cert_lib_->root_cert); + tsi_ssl_root_certs_store_destroy(key_cert_lib_->root_store); + gpr_free(key_cert_lib_); + if (session_cache_ != nullptr) { + tsi_ssl_session_cache_unref(session_cache_); + } + // Unreference others. + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + } + + tsi_test_fixture* GetBaseFixture() { return &base_; } + + void SetVerifyRootCertSubject(bool verify_root_cert_subject) { + verify_root_cert_subject_ = verify_root_cert_subject; + } + + ssl_key_cert_lib* MutableKeyCertLib() { return key_cert_lib_; } + + void SetForceClientAuth(bool force_client_auth) { + force_client_auth_ = force_client_auth; + } + + void SetAlpnMode(AlpnMode alpn_mode) { alpn_lib_->alpn_mode = alpn_mode; } + + void SetServerNameIndication(char* server_name_indication) { + server_name_indication_ = server_name_indication; + } + + void SetSessionCache(tsi_ssl_session_cache* cache) { + session_cache_ = cache; + } + + void SetSessionReused(bool session_reused) { + session_reused_ = session_reused; + } + + void SetSessionTicketKey(const char* session_ticket_key, + size_t session_ticket_key_size) { + session_ticket_key_ = session_ticket_key; + session_ticket_key_size_ = session_ticket_key_size; + } + + void SetBioBufSizes(size_t network_bio_buf_size, size_t ssl_bio_buf_size) { + network_bio_buf_size_ = network_bio_buf_size; + ssl_bio_buf_size_ = ssl_bio_buf_size; + } + + private: + static void SetupHandshakers(tsi_test_fixture* fixture) { + SslTsiTestFixture* ssl_fixture = + reinterpret_cast(fixture); + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->key_cert_lib_, nullptr); + ASSERT_NE(ssl_fixture->alpn_lib_, nullptr); + ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib_; + ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib_; + // Create client handshaker factory. + tsi_ssl_client_handshaker_options client_options; + if (key_cert_lib->use_pem_root_certs) { + client_options.pem_root_certs = key_cert_lib->root_cert; + } + if (ssl_fixture->force_client_auth_) { + client_options.pem_key_cert_pair = + key_cert_lib->use_bad_client_cert + ? &key_cert_lib->bad_client_pem_key_cert_pair + : &key_cert_lib->client_pem_key_cert_pair; + } + if (alpn_lib->alpn_mode == ALPN_CLIENT_NO_SERVER || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { + client_options.alpn_protocols = alpn_lib->client_alpn_protocols; + client_options.num_alpn_protocols = alpn_lib->num_client_alpn_protocols; + } + client_options.root_store = + key_cert_lib->use_root_store ? key_cert_lib->root_store : nullptr; + if (ssl_fixture->session_cache_ != nullptr) { + client_options.session_cache = ssl_fixture->session_cache_; + } + client_options.min_tls_version = ssl_fixture->tls_version_; + client_options.max_tls_version = ssl_fixture->tls_version_; + client_options.skip_server_certificate_verification = + key_cert_lib->skip_server_certificate_verification; + ASSERT_EQ(tsi_create_ssl_client_handshaker_factory_with_options( + &client_options, &ssl_fixture->client_handshaker_factory_), + TSI_OK); + // Create server handshaker factory. + tsi_ssl_server_handshaker_options server_options; + if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { + server_options.alpn_protocols = alpn_lib->server_alpn_protocols; + server_options.num_alpn_protocols = alpn_lib->num_server_alpn_protocols; + if (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { + server_options.num_alpn_protocols--; + } + } + if (key_cert_lib->use_cert_signed_by_intermediate_ca) { + server_options.pem_key_cert_pairs = + key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs; + server_options.num_key_cert_pairs = + key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs; + } else { + server_options.pem_key_cert_pairs = + key_cert_lib->use_bad_server_cert + ? key_cert_lib->bad_server_pem_key_cert_pairs + : key_cert_lib->server_pem_key_cert_pairs; + server_options.num_key_cert_pairs = + key_cert_lib->use_bad_server_cert + ? key_cert_lib->bad_server_num_key_cert_pairs + : key_cert_lib->server_num_key_cert_pairs; + } + server_options.pem_client_root_certs = key_cert_lib->root_cert; + if (ssl_fixture->force_client_auth_) { + server_options.client_certificate_request = + TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; + } else { + server_options.client_certificate_request = + TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + } + server_options.send_client_ca_list = ssl_fixture->send_client_ca_list_; + server_options.session_ticket_key = ssl_fixture->session_ticket_key_; + server_options.session_ticket_key_size = + ssl_fixture->session_ticket_key_size_; + server_options.min_tls_version = ssl_fixture->tls_version_; + server_options.max_tls_version = ssl_fixture->tls_version_; + ASSERT_EQ(tsi_create_ssl_server_handshaker_factory_with_options( + &server_options, &ssl_fixture->server_handshaker_factory_), + TSI_OK); + // Create server and client handshakers. + ASSERT_EQ(tsi_ssl_client_handshaker_factory_create_handshaker( + ssl_fixture->client_handshaker_factory_, + ssl_fixture->server_name_indication_, + ssl_fixture->network_bio_buf_size_, + ssl_fixture->ssl_bio_buf_size_, + &ssl_fixture->base_.client_handshaker), + TSI_OK); + ASSERT_EQ(tsi_ssl_server_handshaker_factory_create_handshaker( + ssl_fixture->server_handshaker_factory_, + ssl_fixture->network_bio_buf_size_, + ssl_fixture->ssl_bio_buf_size_, + &ssl_fixture->base_.server_handshaker), + TSI_OK); + } + + static void CheckAlpn(SslTsiTestFixture* ssl_fixture, + const tsi_peer* peer) { + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->alpn_lib_, nullptr); + ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib_; + const tsi_peer_property* alpn_property = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (alpn_lib->alpn_mode != ALPN_CLIENT_SERVER_OK) { + ASSERT_EQ(alpn_property, nullptr); + } else { + ASSERT_NE(alpn_property, nullptr); + const char* expected_match = "baz"; + ASSERT_EQ(memcmp(alpn_property->value.data, expected_match, + alpn_property->value.length), + 0); + } + } + + static void CheckSecurityLevel(const tsi_peer* peer) { + const tsi_peer_property* security_level = + tsi_peer_get_property_by_name(peer, TSI_SECURITY_LEVEL_PEER_PROPERTY); + ASSERT_NE(security_level, nullptr); + const char* expected_match = "TSI_PRIVACY_AND_INTEGRITY"; + ASSERT_EQ(memcmp(security_level->value.data, expected_match, + security_level->value.length), + 0); + } + + static const tsi_peer_property* CheckBasicAuthenticatedPeerAndGetCommonName( + const tsi_peer* peer) { + const tsi_peer_property* cert_type_property = + tsi_peer_get_property_by_name(peer, + TSI_CERTIFICATE_TYPE_PEER_PROPERTY); + EXPECT_NE(cert_type_property, nullptr); + EXPECT_EQ( + memcmp(cert_type_property->value.data, TSI_X509_CERTIFICATE_TYPE, + cert_type_property->value.length), + 0); + const tsi_peer_property* property = tsi_peer_get_property_by_name( + peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); + EXPECT_NE(property, nullptr); + return property; + } + + static void CheckSessionReusage(SslTsiTestFixture* ssl_fixture, + tsi_peer* peer) { + const tsi_peer_property* session_reused = tsi_peer_get_property_by_name( + peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY); + ASSERT_NE(session_reused, nullptr); + if (ssl_fixture->session_reused_) { + ASSERT_EQ(strncmp(session_reused->value.data, "true", + session_reused->value.length), + 0); + } else { + ASSERT_EQ(strncmp(session_reused->value.data, "false", + session_reused->value.length), + 0); + } + } + + // This is tied specifically to server0.pem loaded by the fixture. + static void CheckServer0Peer(tsi_peer* peer) { + const tsi_peer_property* property = + CheckBasicAuthenticatedPeerAndGetCommonName(peer); + const char* expected_match = "*.test.google.com.au"; + ASSERT_EQ( + memcmp(property->value.data, expected_match, property->value.length), + 0); + ASSERT_EQ(tsi_peer_get_property_by_name( + peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY), + nullptr); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "BAR.TEST.GOOGLE.COM.AU"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "Bar.Test.Google.Com.Au"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bAr.TeST.gOOgle.cOm.AU"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"), + 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.com.au"), 0); + tsi_peer_destruct(peer); + } + + // This is tied specifically to server1.pem loaded by the fixture. + static void CheckServer1Peer(tsi_peer* peer) { + const tsi_peer_property* property = + CheckBasicAuthenticatedPeerAndGetCommonName(peer); + const char* expected_match = "*.test.google.com"; + ASSERT_EQ( + memcmp(property->value.data, expected_match, property->value.length), + 0); + ASSERT_EQ( + check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, + "*.test.google.fr"), + 1); + ASSERT_EQ( + check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, + "waterzooi.test.google.be"), + 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.fr"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.fr"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"), 0); + tsi_peer_destruct(peer); + } + + static void CheckClientPeer(SslTsiTestFixture* ssl_fixture, + tsi_peer* peer) { + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->alpn_lib_, nullptr); + ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib_; + if (!ssl_fixture->force_client_auth_) { + ASSERT_EQ(peer->property_count, + (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 3 : 2)); + } else { + const tsi_peer_property* property = + CheckBasicAuthenticatedPeerAndGetCommonName(peer); + const char* expected_match = "testclient"; + ASSERT_EQ(memcmp(property->value.data, expected_match, + property->value.length), + 0); + } + tsi_peer_destruct(peer); + } + + static void CheckVerifiedRootCertSubject(const tsi_peer* peer) { + const tsi_peer_property* verified_root_cert_subject = + tsi_peer_get_property_by_name( + peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); + ASSERT_NE(verified_root_cert_subject, nullptr); + const char* expected_match = + "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; + ASSERT_EQ(memcmp(verified_root_cert_subject->value.data, expected_match, + verified_root_cert_subject->value.length), + 0); + } + + static void CheckVerifiedRootCertSubjectUnset(const tsi_peer* peer) { + const tsi_peer_property* verified_root_cert_subject = + tsi_peer_get_property_by_name( + peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); + ASSERT_EQ(verified_root_cert_subject, nullptr); + } + + static void CheckHandshakerPeers(tsi_test_fixture* fixture) { + SslTsiTestFixture* ssl_fixture = + reinterpret_cast(fixture); + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->key_cert_lib_, nullptr); + ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib_; + tsi_peer peer; + // In TLS 1.3, the client-side handshake succeeds even if the client sends + // a bad certificate. In such a case, the server would fail the TLS + // handshake and send an alert to the client as the first application data + // message. In TLS 1.2, the client-side handshake will fail if the client + // sends a bad certificate. + // + // For OpenSSL versions < 1.1, TLS 1.3 is not supported, so the + // client-side handshake should succeed precisely when the server-side + // handshake succeeds. + bool expect_server_success = !(key_cert_lib->use_bad_server_cert || + (key_cert_lib->use_bad_client_cert && + ssl_fixture->force_client_auth_)); +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + bool expect_client_success = + ssl_fixture->tls_version_ == tsi_tls_version::TSI_TLS1_2 + ? expect_server_success + : !key_cert_lib->use_bad_server_cert; +#else + bool expect_client_success = expect_server_success; +#endif + if (expect_client_success) { + ASSERT_EQ(tsi_handshaker_result_extract_peer( + ssl_fixture->base_.client_result, &peer), + TSI_OK); + CheckSessionReusage(ssl_fixture, &peer); + CheckAlpn(ssl_fixture, &peer); + CheckSecurityLevel(&peer); + if (ssl_fixture->verify_root_cert_subject_) { + if (!ssl_fixture->session_reused_) { + CheckVerifiedRootCertSubject(&peer); + } else { + CheckVerifiedRootCertSubjectUnset(&peer); + } + } + if (ssl_fixture->server_name_indication_ == nullptr || + strcmp(ssl_fixture->server_name_indication_, + SSL_TSI_TEST_WRONG_SNI) == 0 || + strcmp(ssl_fixture->server_name_indication_, + SSL_TSI_TEST_INVALID_SNI) == 0) { + // Expect server to use default server0.pem. + CheckServer0Peer(&peer); + } else { + // Expect server to use server1.pem. + CheckServer1Peer(&peer); + } + } else { + ASSERT_EQ(ssl_fixture->base_.client_result, nullptr); + } + if (expect_server_success) { + ASSERT_EQ(tsi_handshaker_result_extract_peer( + ssl_fixture->base_.server_result, &peer), + TSI_OK); + CheckSessionReusage(ssl_fixture, &peer); + CheckAlpn(ssl_fixture, &peer); + CheckSecurityLevel(&peer); + if (ssl_fixture->force_client_auth_ && !ssl_fixture->session_reused_) { + CheckVerifiedRootCertSubject(&peer); + } else { + CheckVerifiedRootCertSubjectUnset(&peer); + } + CheckClientPeer(ssl_fixture, &peer); + } else { + ASSERT_EQ(ssl_fixture->base_.server_result, nullptr); + } + } + + static void Destruct(tsi_test_fixture* fixture) { + auto* self = reinterpret_cast(fixture); + delete self; + } + + static tsi_test_fixture_vtable kVtable; + + tsi_test_fixture base_; + ssl_key_cert_lib* key_cert_lib_ = nullptr; + ssl_alpn_lib* alpn_lib_; + bool force_client_auth_; + char* server_name_indication_ = nullptr; + tsi_ssl_session_cache* session_cache_ = nullptr; + bool session_reused_; + const char* session_ticket_key_ = nullptr; + size_t session_ticket_key_size_; + size_t network_bio_buf_size_; + size_t ssl_bio_buf_size_; + bool verify_root_cert_subject_; + tsi_tls_version tls_version_; + bool send_client_ca_list_; + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; + tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; + }; -void ssl_tsi_test_do_handshake_tiny_handshake_buffer() { + SslTransportSecurityTest() { grpc_init(); } + + ~SslTransportSecurityTest() override { + DestroyFixture(); + grpc_shutdown(); + } + + void SetUpSslFixture(tsi_tls_version tls_version, bool send_client_ca_list) { + ssl_fixture_ = new SslTsiTestFixture(tls_version, send_client_ca_list); + ssl_tsi_test_fixture_ = ssl_fixture_->GetBaseFixture(); + fixture_destroyed = false; + } + + void DoHandshake() { tsi_test_do_handshake(ssl_tsi_test_fixture_); } + + void DoRoundTrip() { tsi_test_do_round_trip(ssl_tsi_test_fixture_); } + + void DestroyFixture() { + if (fixture_destroyed) { + return; + } + tsi_test_fixture_destroy(ssl_tsi_test_fixture_); + fixture_destroyed = true; + } + + tsi_test_fixture* ssl_tsi_test_fixture_; + SslTsiTestFixture* ssl_fixture_; + bool fixture_destroyed = true; +}; + +tsi_test_fixture_vtable SslTransportSecurityTest::SslTsiTestFixture::kVtable = { + SslTransportSecurityTest::SslTsiTestFixture::SetupHandshakers, + SslTransportSecurityTest::SslTsiTestFixture::CheckHandshakerPeers, + SslTransportSecurityTest::SslTsiTestFixture::Destruct}; + +INSTANTIATE_TEST_SUITE_P( + SslTestGroup, SslTransportSecurityTest, + testing::Combine(testing::Values(TSI_TLS1_2, TSI_TLS1_3), + testing::Values(true, false)), + [](const testing::TestParamInfo& + info) { + return absl::StrCat( + std::get<0>(info.param) == TSI_TLS1_2 ? "tls_12" : "tls_13", "_", + std::get<1>(info.param) ? "send_client_ca_list" + : "no_send_client_ca_list"); + }); + +TEST_P(SslTransportSecurityTest, DoHandshakeTinyHandshakeBuffer) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_tiny_handshake_buffer"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - fixture->handshake_buffer_size = TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE; + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_tsi_test_fixture_->handshake_buffer_size = + TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE; // Handshake buffer is too small to hold both handshake messages and the // unused bytes. - fixture->test_unused_bytes = false; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_tsi_test_fixture_->test_unused_bytes = false; + DoHandshake(); } -void ssl_tsi_test_do_handshake_small_handshake_buffer() { +TEST_P(SslTransportSecurityTest, DoHandshakeSmallHandshakeBuffer) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_small_handshake_buffer"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - fixture->handshake_buffer_size = TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_tsi_test_fixture_->handshake_buffer_size = + TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE; + DoHandshake(); } -void ssl_tsi_test_do_handshake() { +TEST_P(SslTransportSecurityTest, DoHandshake) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_root_store() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithRootStore) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_root_store"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->key_cert_lib->use_root_store = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->MutableKeyCertLib()->use_root_store = true; + DoHandshake(); } -void ssl_tsi_test_do_handshake_skipping_server_certificate_verification() { +// TODO(gregorycooke) - failing with OpenSSL1.0.2 +#if OPENSSL_VERSION_NUMBER >= 0x10100000 +TEST_P(SslTransportSecurityTest, + DoHandshakeSkippingServerCertificateVerification) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_skipping_server_certificate_verification"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->verify_root_cert_subject = false; - ssl_fixture->key_cert_lib->use_root_store = false; - ssl_fixture->key_cert_lib->use_pem_root_certs = false; - ssl_fixture->key_cert_lib->skip_server_certificate_verification = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetVerifyRootCertSubject(false); + ssl_key_cert_lib* key_cert_lib = ssl_fixture_->MutableKeyCertLib(); + key_cert_lib->use_root_store = false; + key_cert_lib->use_pem_root_certs = false; + key_cert_lib->skip_server_certificate_verification = true; + DoHandshake(); } +#endif -void ssl_tsi_test_do_handshake_with_large_server_handshake_messages( - const std::string& trust_bundle) { +TEST_P(SslTransportSecurityTest, DoHandshakeWithLargeServerHandshakeMessages) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_large_server_handshake_messages"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); + std::string trust_bundle = GenerateTrustBundle(); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // Force the test to read more handshake bytes from the peer than we have room // for in the BIO. The default BIO buffer size is 17kB. - fixture->handshake_buffer_size = 18000; - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); + ssl_tsi_test_fixture_->handshake_buffer_size = 18000; // Make a copy of the root cert and free the original. - std::string root_cert(ssl_fixture->key_cert_lib->root_cert); - gpr_free(ssl_fixture->key_cert_lib->root_cert); - ssl_fixture->key_cert_lib->root_cert = nullptr; + ssl_key_cert_lib* key_cert_lib = ssl_fixture_->MutableKeyCertLib(); + std::string root_cert(key_cert_lib->root_cert); + gpr_free(key_cert_lib->root_cert); + key_cert_lib->root_cert = nullptr; // Create a new root store, consisting of the root cert that is actually // needed and 200 self-signed certs. std::string effective_trust_bundle = absl::StrCat(root_cert, trust_bundle); - tsi_ssl_root_certs_store_destroy(ssl_fixture->key_cert_lib->root_store); - ssl_fixture->key_cert_lib->root_cert = - const_cast(effective_trust_bundle.c_str()); - ssl_fixture->key_cert_lib->root_store = + tsi_ssl_root_certs_store_destroy(key_cert_lib->root_store); + key_cert_lib->root_cert = const_cast(effective_trust_bundle.c_str()); + key_cert_lib->root_store = tsi_ssl_root_certs_store_create(effective_trust_bundle.c_str()); - ssl_fixture->key_cert_lib->use_root_store = true; - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); + key_cert_lib->use_root_store = true; + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); // Overwrite the root_cert pointer so that tsi_test_fixture_destroy does not // try to gpr_free it. - ssl_fixture->key_cert_lib->root_cert = nullptr; - tsi_test_fixture_destroy(fixture); + key_cert_lib->root_cert = nullptr; } -void ssl_tsi_test_do_handshake_with_client_authentication() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithClientAuthentication) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_client_authentication"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_client_authentication_and_root_store() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithClientAuthenticationAndRootStore) { gpr_log( GPR_INFO, "ssl_tsi_test_do_handshake_with_client_authentication_and_root_store"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->force_client_auth = true; - ssl_fixture->key_cert_lib->use_root_store = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetForceClientAuth(true); + ssl_fixture_->MutableKeyCertLib()->use_root_store = true; + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithServerNameIndicationExactDomain) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // server1 cert contains "waterzooi.test.google.be" in SAN. - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->server_name_indication = - const_cast("waterzooi.test.google.be"); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast("waterzooi.test.google.be")); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithServerNameIndicationWildStarDomain) { gpr_log( GPR_INFO, "ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // server1 cert contains "*.test.google.fr" in SAN. - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->server_name_indication = - const_cast("juju.test.google.fr"); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast("juju.test.google.fr")); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_wrong_server_name_indication() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithWrongServerNameIndication) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_wrong_server_name_indication"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // server certs do not contain "test.google.cn". - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->server_name_indication = - const_cast(SSL_TSI_TEST_WRONG_SNI); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast(SSL_TSI_TEST_WRONG_SNI)); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_invalid_and_ignored_server_name_indication() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithInvalidAndIgnoredServerNameIndication) { gpr_log(GPR_INFO, - "ssl_tsi_test_do_handshake_with_wrong_server_name_indication"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); + "ssl_tsi_test_do_handshake_with_invalid_and_ignored_server_name_" + "indication"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // SNI that's an IP address will be ignored. - ssl_fixture->server_name_indication = - const_cast(SSL_TSI_TEST_INVALID_SNI); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast(SSL_TSI_TEST_INVALID_SNI)); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_bad_server_cert() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithBadServerCert) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_bad_server_cert"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->key_cert_lib->use_bad_server_cert = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->MutableKeyCertLib()->use_bad_server_cert = true; + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_bad_client_cert() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithBadClientCert) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_bad_client_cert"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->key_cert_lib->use_bad_client_cert = true; - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->MutableKeyCertLib()->use_bad_client_cert = true; + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); } -void ssl_tsi_test_do_handshake_alpn_client_no_server() { +#ifdef OPENSSL_IS_BORINGSSL +// BoringSSL and OpenSSL have different behaviors on mismatched ALPN. +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnClientNoServer) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_no_server"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_NO_SERVER; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); -} - -void ssl_tsi_test_do_handshake_alpn_server_no_client() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_server_no_client"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_SERVER_NO_CLIENT; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_CLIENT_NO_SERVER); + DoHandshake(); } -void ssl_tsi_test_do_handshake_alpn_client_server_mismatch() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_server_no_client"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_MISMATCH; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnClientServerMismatch) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_server_mismatch"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_CLIENT_SERVER_MISMATCH); + DoHandshake(); } -void ssl_tsi_test_do_handshake_alpn_client_server_ok() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_server_ok"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_OK; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); -} - -void ssl_tsi_test_do_round_trip_for_all_configs() { +TEST_P(SslTransportSecurityTest, DoRoundTripForAllConfigs) { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_for_all_configs"); unsigned int* bit_array = static_cast( gpr_zalloc(sizeof(unsigned int) * TSI_TEST_NUM_OF_ARGUMENTS)); @@ -849,31 +906,30 @@ void ssl_tsi_test_do_round_trip_for_all_configs() { bit_array[ind] = (v & mask) ? 1 : 0; v <<= 1; } - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - tsi_test_frame_protector_config_destroy(ssl_fixture->base.config); - ssl_fixture->base.config = tsi_test_frame_protector_config_create( + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + tsi_test_frame_protector_config_destroy(ssl_tsi_test_fixture_->config); + ssl_tsi_test_fixture_->config = tsi_test_frame_protector_config_create( bit_array[0], bit_array[1], bit_array[2], bit_array[3], bit_array[4], bit_array[5], bit_array[6]); - tsi_test_do_round_trip(&ssl_fixture->base); - tsi_test_fixture_destroy(fixture); + DoRoundTrip(); + DestroyFixture(); } gpr_free(bit_array); } -void ssl_tsi_test_do_round_trip_with_error_on_stack() { +TEST_P(SslTransportSecurityTest, DoRoundTripWithErrorOnStack) { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_with_error_on_stack"); // Invoke an SSL function that causes an error, and ensure the error // makes it to the stack. ASSERT_FALSE(EC_KEY_new_by_curve_name(NID_rsa)); ASSERT_NE(ERR_peek_error(), 0); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - tsi_test_do_round_trip(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + DoRoundTrip(); } -void ssl_tsi_test_do_round_trip_odd_buffer_size() { +TEST_P(SslTransportSecurityTest, DoRoundTripOddBufferSize) { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_odd_buffer_size"); const size_t odd_sizes[] = {1025, 2051, 4103, 8207, 16409}; size_t size = sizeof(odd_sizes) / sizeof(size_t); @@ -890,14 +946,14 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() { for (size_t ind3 = 0; ind3 < size; ind3++) { for (size_t ind4 = 0; ind4 < size; ind4++) { for (size_t ind5 = 0; ind5 < size; ind5++) { - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); tsi_test_frame_protector_config_set_buffer_size( - ssl_fixture->base.config, odd_sizes[ind1], odd_sizes[ind2], - odd_sizes[ind3], odd_sizes[ind4], odd_sizes[ind5]); - tsi_test_do_round_trip(&ssl_fixture->base); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->GetBaseFixture()->config, odd_sizes[ind1], + odd_sizes[ind2], odd_sizes[ind3], odd_sizes[ind4], + odd_sizes[ind5]); + DoRoundTrip(); + DestroyFixture(); } } } @@ -905,24 +961,23 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() { } } -void ssl_tsi_test_do_handshake_session_cache() { +TEST_P(SslTransportSecurityTest, DoHandshakeSessionCache) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_session_cache"); tsi_ssl_session_cache* session_cache = tsi_ssl_session_cache_create_lru(16); char session_ticket_key[kSessionTicketEncryptionKeySize]; - auto do_handshake = [&session_ticket_key, + auto do_handshake = [this, &session_ticket_key, &session_cache](bool session_reused) { - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->server_name_indication = - const_cast("waterzooi.test.google.be"); - ssl_fixture->session_ticket_key = session_ticket_key; - ssl_fixture->session_ticket_key_size = sizeof(session_ticket_key); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetServerNameIndication( + const_cast("waterzooi.test.google.be")); + ssl_fixture_->SetSessionTicketKey(session_ticket_key, + sizeof(session_ticket_key)); tsi_ssl_session_cache_ref(session_cache); - ssl_fixture->session_cache = session_cache; - ssl_fixture->session_reused = session_reused; - tsi_test_do_round_trip(&ssl_fixture->base); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetSessionCache(session_cache); + ssl_fixture_->SetSessionReused(session_reused); + DoRoundTrip(); + DestroyFixture(); }; memset(session_ticket_key, 'a', sizeof(session_ticket_key)); do_handshake(false); @@ -937,19 +992,35 @@ void ssl_tsi_test_do_handshake_session_cache() { do_handshake(true); tsi_ssl_session_cache_unref(session_cache); } +#endif // OPENSSL_IS_BORINGSSL -void ssl_tsi_test_do_handshake_with_intermediate_ca() { - gpr_log( - GPR_INFO, - "ssl_tsi_test_do_handshake_with_client_authentication_and_root_store"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->force_client_auth = true; - ssl_fixture->key_cert_lib->use_root_store = true; - ssl_fixture->key_cert_lib->use_cert_signed_by_intermediate_ca = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnServerNoClient) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_server_no_client"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_SERVER_NO_CLIENT); + DoHandshake(); +} + +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnClientServerOk) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_server_ok"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_CLIENT_SERVER_OK); + DoHandshake(); +} + +TEST_P(SslTransportSecurityTest, DoHandshakeWithCustomBioPair) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_custom_bio_pair"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + ssl_fixture_->SetBioBufSizes( + /*network_bio_buf_size=*/TSI_TEST_DEFAULT_BUFFER_SIZE, + /*ssl_bio_buf_size=*/256); +#endif + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); } static const tsi_ssl_handshaker_factory_vtable* original_vtable; @@ -967,7 +1038,7 @@ static void ssl_tsi_test_handshaker_factory_destructor( static tsi_ssl_handshaker_factory_vtable test_handshaker_factory_vtable = { ssl_tsi_test_handshaker_factory_destructor}; -void test_tsi_ssl_client_handshaker_factory_refcounting() { +TEST(SslTransportSecurityTest, TestClientHandshakerFactoryRefcounting) { int i; char* cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.pem"); @@ -1012,7 +1083,7 @@ void test_tsi_ssl_client_handshaker_factory_refcounting() { gpr_free(cert_chain); } -void test_tsi_ssl_server_handshaker_factory_refcounting() { +TEST(SslTransportSecurityTest, TestServerHandshakerFactoryRefcounting) { int i; tsi_ssl_server_handshaker_factory* server_handshaker_factory; tsi_handshaker* handshaker[3]; @@ -1059,7 +1130,7 @@ void test_tsi_ssl_server_handshaker_factory_refcounting() { // Attempting to create a handshaker factory with invalid parameters should fail // but not crash. -void test_tsi_ssl_client_handshaker_factory_bad_params() { +TEST(SslTransportSecurityTest, TestClientHandshakerFactoryBadParams) { const char* cert_chain = "This is not a valid PEM file."; tsi_ssl_client_handshaker_factory* client_handshaker_factory; @@ -1071,14 +1142,7 @@ void test_tsi_ssl_client_handshaker_factory_bad_params() { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory); } -void ssl_tsi_test_handshaker_factory_internals() { - gpr_log(GPR_INFO, "ssl_tsi_test_handshaker_factory_internals"); - test_tsi_ssl_client_handshaker_factory_refcounting(); - test_tsi_ssl_server_handshaker_factory_refcounting(); - test_tsi_ssl_client_handshaker_factory_bad_params(); -} - -void ssl_tsi_test_duplicate_root_certificates() { +TEST(SslTransportSecurityTest, DuplicateRootCertificates) { gpr_log(GPR_INFO, "ssl_tsi_test_duplicate_root_certificates"); char* root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); char* dup_root_cert = static_cast( @@ -1094,7 +1158,7 @@ void ssl_tsi_test_duplicate_root_certificates() { gpr_free(dup_root_cert); } -void ssl_tsi_test_extract_x509_subject_names() { +TEST(SslTransportSecurityTest, ExtractX509SubjectNames) { gpr_log(GPR_INFO, "ssl_tsi_test_extract_x509_subject_names"); char* cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "multi-domain.pem"); tsi_peer peer; @@ -1198,7 +1262,7 @@ void ssl_tsi_test_extract_x509_subject_names() { tsi_peer_destruct(&peer); } -void ssl_tsi_test_extract_cert_chain() { +TEST(SslTransportSecurityTest, ExtractCertChain) { gpr_log(GPR_INFO, "ssl_tsi_test_extract_cert_chain"); char* cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.pem"); char* ca = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); @@ -1238,74 +1302,6 @@ void ssl_tsi_test_extract_cert_chain() { sk_X509_pop_free(cert_chain, X509_free); } -void ssl_tsi_test_do_handshake_with_custom_bio_pair() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_custom_bio_pair"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - ssl_fixture->network_bio_buf_size = TSI_TEST_DEFAULT_BUFFER_SIZE; - ssl_fixture->ssl_bio_buf_size = 256; -#endif - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); -} - -TEST(SslTransportSecurityTest, MainTest) { - grpc_init(); - std::string trust_bundle = GenerateTrustBundle(); - const size_t number_tls_versions = 2; - const tsi_tls_version tls_versions[] = {tsi_tls_version::TSI_TLS1_2, - tsi_tls_version::TSI_TLS1_3}; - for (size_t i = 0; i < number_tls_versions; i++) { - // Set the TLS version to be used in the tests. - test_tls_version = tls_versions[i]; - for (bool send_client_ca_list : {true, false}) { - test_send_client_ca_list = send_client_ca_list; - ssl_tsi_test_do_handshake_tiny_handshake_buffer(); - ssl_tsi_test_do_handshake_small_handshake_buffer(); - ssl_tsi_test_do_handshake(); - ssl_tsi_test_do_handshake_with_root_store(); - ssl_tsi_test_do_handshake_with_large_server_handshake_messages( - trust_bundle); - ssl_tsi_test_do_handshake_with_client_authentication(); - ssl_tsi_test_do_handshake_with_client_authentication_and_root_store(); - ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain(); - ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain(); - ssl_tsi_test_do_handshake_with_invalid_and_ignored_server_name_indication(); - ssl_tsi_test_do_handshake_with_wrong_server_name_indication(); - ssl_tsi_test_do_handshake_with_bad_server_cert(); - ssl_tsi_test_do_handshake_with_bad_client_cert(); -// TODO(gregorycooke) - failing with OpenSSL1.0.2 -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - ssl_tsi_test_do_handshake_skipping_server_certificate_verification(); -#endif // OPENSSL_VERSION_NUMBER >= 0x10100000 - -#ifdef OPENSSL_IS_BORINGSSL - // BoringSSL and OpenSSL have different behaviors on mismatched ALPN. - ssl_tsi_test_do_handshake_alpn_client_no_server(); - ssl_tsi_test_do_handshake_alpn_client_server_mismatch(); - // These tests fail with openssl3 and openssl111 currently but not - // boringssl - ssl_tsi_test_do_handshake_session_cache(); - ssl_tsi_test_do_round_trip_for_all_configs(); - ssl_tsi_test_do_round_trip_with_error_on_stack(); - ssl_tsi_test_do_round_trip_odd_buffer_size(); -#endif - ssl_tsi_test_do_handshake_alpn_server_no_client(); - ssl_tsi_test_do_handshake_alpn_client_server_ok(); - ssl_tsi_test_handshaker_factory_internals(); - ssl_tsi_test_duplicate_root_certificates(); - ssl_tsi_test_extract_x509_subject_names(); - ssl_tsi_test_extract_cert_chain(); - ssl_tsi_test_do_handshake_with_custom_bio_pair(); - ssl_tsi_test_do_handshake_with_intermediate_ca(); - } - } - grpc_shutdown(); -} - int main(int argc, char** argv) { grpc::testing::TestEnvironment env(&argc, argv); ::testing::InitGoogleTest(&argc, argv); From e5cd63f971ffbeef9afc6c6efbea85f10dd80477 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Fri, 10 May 2024 19:49:00 -0700 Subject: [PATCH 24/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36575) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36575 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36575 from tanvi-jagtap:test_core_e2e_all ef6f23db8c4d4a48818d94501492d3382ce57af4 PiperOrigin-RevId: 632669009 --- test/core/end2end/BUILD | 27 ++++++++++-- test/core/end2end/bad_server_response_test.cc | 19 ++++---- test/core/end2end/connection_refused_test.cc | 8 ++-- test/core/end2end/cq_verifier.cc | 15 +++---- test/core/end2end/dualstack_socket_test.cc | 27 ++++++------ test/core/end2end/end2end_tests.cc | 7 +-- .../end2end/fixtures/http_proxy_fixture.cc | 8 ++-- test/core/end2end/fixtures/proxy.cc | 6 +-- test/core/end2end/fuzzers/BUILD | 2 + test/core/end2end/fuzzers/fuzzing_common.cc | 3 +- test/core/end2end/fuzzers/network_input.cc | 4 +- test/core/end2end/goaway_server_test.cc | 7 ++- test/core/end2end/grpc_core_end2end_test.bzl | 3 ++ test/core/end2end/h2_ssl_cert_test.cc | 6 +-- .../end2end/invalid_call_argument_test.cc | 44 +++++++++---------- test/core/end2end/no_server_test.cc | 6 +-- test/core/end2end/tests/call_creds.cc | 14 +++--- .../core/end2end/tests/disappearing_server.cc | 6 +-- test/core/end2end/tests/filter_context.cc | 8 ++-- .../end2end/tests/resource_quota_server.cc | 12 ++--- test/core/end2end/tests/server_streaming.cc | 4 +- .../end2end/tests/simple_delayed_request.cc | 8 ++-- test/core/end2end/tests/simple_request.cc | 4 +- .../tests/timeout_before_request_call.cc | 3 +- 24 files changed, 134 insertions(+), 117 deletions(-) diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 08c373e425d..597fb7c0c26 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -28,6 +28,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", "absl/types:variant", @@ -64,6 +65,7 @@ grpc_cc_library( hdrs = ["fixtures/http_proxy_fixture.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -96,7 +98,10 @@ grpc_cc_library( name = "proxy", srcs = ["fixtures/proxy.cc"], hdrs = ["fixtures/proxy.h"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "//:channel_arg_names", @@ -120,6 +125,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/memory", "absl/meta:type_traits", "absl/random", @@ -500,7 +506,10 @@ grpc_core_end2end_test(name = "write_buffering_at_end") grpc_cc_test( name = "bad_server_response_test", srcs = ["bad_server_response_test.cc"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "cq_verifier", @@ -523,7 +532,10 @@ grpc_cc_test( grpc_cc_test( name = "connection_refused_test", srcs = ["connection_refused_test.cc"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "cq_verifier", @@ -541,6 +553,7 @@ grpc_cc_test( srcs = ["dualstack_socket_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/strings:str_format", @@ -565,6 +578,7 @@ grpc_cc_test( srcs = ["goaway_server_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -596,7 +610,10 @@ grpc_cc_test( grpc_cc_test( name = "invalid_call_argument_test", srcs = ["invalid_call_argument_test.cc"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "cq_verifier", @@ -623,6 +640,7 @@ grpc_cc_test( srcs = ["no_server_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/time", @@ -652,6 +670,7 @@ grpc_cc_test( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/memory", "absl/meta:type_traits", "absl/strings", diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index eb9b0c09a2f..b2c38dba64a 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -25,6 +25,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -35,7 +36,6 @@ #include #include #include -#include #include #include @@ -135,8 +135,7 @@ static void handle_write() { static void handle_read(void* /*arg*/, grpc_error_handle error) { if (!error.ok()) { - gpr_log(GPR_ERROR, "handle_read error: %s", - grpc_core::StatusToString(error).c_str()); + LOG(ERROR) << "handle_read error: " << grpc_core::StatusToString(error); return; } state.incoming_data_length += state.temp_incoming_buffer.length; @@ -145,15 +144,13 @@ static void handle_read(void* /*arg*/, grpc_error_handle error) { for (i = 0; i < state.temp_incoming_buffer.count; i++) { char* dump = grpc_dump_slice(state.temp_incoming_buffer.slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "Server received: %s", dump); + VLOG(2) << "Server received: " << dump; gpr_free(dump); } - gpr_log(GPR_DEBUG, - "got %" PRIuPTR " bytes, expected %" PRIuPTR - " bytes or a non-HTTP2 response to be sent", - state.incoming_data_length, - SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD); + VLOG(2) << "got " << state.incoming_data_length << " bytes, expected " + << SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD + << " bytes or a non-HTTP2 response to be sent"; if (state.incoming_data_length >= SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD || !state.http2_response) { @@ -299,8 +296,8 @@ static void actually_poll_server(void* arg) { bool done = gpr_atm_acq_load(&state.done_atm) != 0; gpr_timespec time_left = gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); - gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, - time_left.tv_sec, time_left.tv_nsec); + VLOG(2) << "done=" << done << ", time_left=" << time_left.tv_sec << "." + << time_left.tv_nsec; if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) { break; } diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 055e115a286..1e3414b8875 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include "src/core/lib/channel/channel_args.h" @@ -49,8 +49,8 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_status_code status; grpc_slice details; - gpr_log(GPR_INFO, "TEST: wait_for_ready=%d use_service_config=%d", - wait_for_ready, use_service_config); + LOG(INFO) << "TEST: wait_for_ready=" << wait_for_ready + << " use_service_config=" << use_service_config; grpc_init(); @@ -81,7 +81,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) { // create a call, channel to a port which will refuse connection int port = grpc_pick_unused_port_or_die(); std::string addr = grpc_core::JoinHostPort("127.0.0.1", port); - gpr_log(GPR_INFO, "server: %s", addr.c_str()); + LOG(INFO) << "server: " << addr; grpc_channel_credentials* creds = grpc_insecure_credentials_create(); chan = grpc_channel_create(addr.c_str(), creds, args); grpc_channel_credentials_release(creds); diff --git a/test/core/end2end/cq_verifier.cc b/test/core/end2end/cq_verifier.cc index c318f7fa301..c0bc5b66f97 100644 --- a/test/core/end2end/cq_verifier.cc +++ b/test/core/end2end/cq_verifier.cc @@ -29,6 +29,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -41,7 +42,6 @@ #include #include #include -#include #include #include "src/core/lib/compression/message_compress.h" @@ -126,9 +126,8 @@ int raw_byte_buffer_eq_slice(grpc_byte_buffer* rbb, grpc_slice b) { 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a)); if (!ok) { - gpr_log(GPR_ERROR, - "SLICE MISMATCH: left_length=%" PRIuPTR " right_length=%" PRIuPTR, - GRPC_SLICE_LENGTH(a), GRPC_SLICE_LENGTH(b)); + LOG(ERROR) << "SLICE MISMATCH: left_length=" << GRPC_SLICE_LENGTH(a) + << " right_length=" << GRPC_SLICE_LENGTH(b); std::string out; const char* a_str = reinterpret_cast(GRPC_SLICE_START_PTR(a)); const char* b_str = reinterpret_cast(GRPC_SLICE_START_PTR(b)); @@ -151,7 +150,7 @@ int raw_byte_buffer_eq_slice(grpc_byte_buffer* rbb, grpc_slice b) { absl::CEscape(absl::string_view(&b_str[i], 1)), "\u001b[0m"); } - gpr_log(GPR_ERROR, "%s", out.c_str()); + LOG(ERROR) << out; } } grpc_slice_unref(a); @@ -365,8 +364,7 @@ void CqVerifier::Verify(Duration timeout, SourceLocation location) { while (!expectations_.empty()) { must_log = std::exchange(added_expectations_, false) || must_log; if (log_verifications_ && must_log) { - gpr_log(GPR_ERROR, "Verify %s for %s", ToShortString().c_str(), - timeout.ToString().c_str()); + LOG(ERROR) << "Verify " << ToShortString() << " for " << timeout; } must_log = false; grpc_event ev = Step(deadline); @@ -423,8 +421,7 @@ bool CqVerifier::AllMaybes() const { void CqVerifier::VerifyEmpty(Duration timeout, SourceLocation location) { if (log_verifications_) { - gpr_log(GPR_ERROR, "Verify empty completion queue for %s", - timeout.ToString().c_str()); + LOG(ERROR) << "Verify empty completion queue for " << timeout; } const gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout.as_timespec()); diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index bf793e97bec..33ab2091c1b 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/statusor.h" #include @@ -47,7 +48,6 @@ #include #include #include -#include #include "src/core/lib/address_utils/sockaddr_utils.h" #include "src/core/lib/gprpp/host_port.h" @@ -78,7 +78,7 @@ static void log_resolved_addrs(const char* label, const char* hostname) { return; } for (const auto& addr : *addresses_or) { - gpr_log(GPR_INFO, "%s: %s", label, grpc_sockaddr_to_uri(&addr)->c_str()); + LOG(INFO) << label << ": " << grpc_sockaddr_to_uri(&addr)->c_str(); } } @@ -152,9 +152,9 @@ void test_connect(const char* server_host, const char* client_host, int port, client = grpc_channel_create(client_hostport.c_str(), creds, nullptr); grpc_channel_credentials_release(creds); - gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", - server_hostport.c_str(), client_hostport.c_str(), - expect_ok ? "success" : "failure"); + LOG(INFO) << "Testing with server=" << server_hostport.c_str() + << " client=" << client_hostport.c_str() << " (expecting " + << (expect_ok ? "success" : "failure") << ")"; log_resolved_addrs("server resolved addr", server_host); log_resolved_addrs("client resolved addr", client_host); @@ -236,7 +236,7 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv.Verify(); peer = grpc_call_get_peer(c); - gpr_log(GPR_DEBUG, "got peer: '%s'", peer); + VLOG(2) << "got peer: '" << peer << "'"; gpr_free(peer); CHECK_EQ(status, GRPC_STATUS_UNIMPLEMENTED); @@ -251,8 +251,8 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv.Expect(grpc_core::CqVerifier::tag(1), true); cqv.Verify(); - gpr_log(GPR_INFO, "status: %d (expected: %d)", status, - GRPC_STATUS_UNAVAILABLE); + LOG(INFO) << "status: " << status + << " (expected: " << GRPC_STATUS_UNAVAILABLE << ")"; CHECK_EQ(status, GRPC_STATUS_UNAVAILABLE); } @@ -301,10 +301,9 @@ int external_dns_works(const char* host) { // dualstack_socket_test from functioning correctly). See b/201064791. if (grpc_sockaddr_to_uri(&addr).value() == "ipv6:%5B64:ff9b::7f00:1%5D:80") { - gpr_log( - GPR_INFO, - "Detected DNS64 server response. Tests that depend on " - "*.unittest.grpc.io. will be skipped as they won't work with DNS64."); + LOG(INFO) << "Detected DNS64 server response. Tests that depend on " + "*.unittest.grpc.io. will be skipped as they won't work " + "with DNS64."; result = 0; break; } @@ -319,7 +318,7 @@ int main(int argc, char** argv) { grpc_init(); if (!grpc_ipv6_loopback_available()) { - gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests."); + LOG(INFO) << "Can't bind to ::1. Skipping IPv6 tests."; do_ipv6 = 0; } @@ -360,7 +359,7 @@ int main(int argc, char** argv) { if (!external_dns_works("loopback4.unittest.grpc.io") || !external_dns_works("loopback46.unittest.grpc.io")) { - gpr_log(GPR_INFO, "Skipping tests that depend on *.unittest.grpc.io."); + LOG(INFO) << "Skipping tests that depend on *.unittest.grpc.io."; } else { test_connect("loopback46.unittest.grpc.io", "loopback4.unittest.grpc.io", 0, 1); diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 30615b1698a..51505c91fd5 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -23,6 +23,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/random/random.h" @@ -117,7 +118,7 @@ void CoreEnd2endTest::TearDown() { // This will wait until gRPC shutdown has actually happened to make sure // no gRPC resources (such as thread) are active. (timeout = 10s) if (!grpc_wait_until_shutdown(10)) { - gpr_log(GPR_ERROR, "Timeout in waiting for gRPC shutdown"); + LOG(ERROR) << "Timeout in waiting for gRPC shutdown"; } } CHECK_EQ(client_, nullptr); @@ -153,8 +154,8 @@ std::string CoreEnd2endTest::IncomingMessage::payload() const { grpc_slice_buffer decompressed_buffer; grpc_slice_buffer_init(&decompressed_buffer); CHECK(grpc_msg_decompress(payload_->data.raw.compression, - &payload_->data.raw.slice_buffer, - &decompressed_buffer)); + &payload_->data.raw.slice_buffer, + &decompressed_buffer)); grpc_byte_buffer* rbb = grpc_raw_byte_buffer_create( decompressed_buffer.slices, decompressed_buffer.count); grpc_byte_buffer_reader reader; diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index be2ec412014..3eca777e098 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -27,6 +27,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/escaping.h" @@ -37,7 +38,6 @@ #include #include #include -#include #include #include "src/core/lib/address_utils/sockaddr_utils.h" @@ -510,8 +510,8 @@ static bool proxy_auth_header_matches(absl::string_view proxy_auth_header_val, // which will cause the client connection to be dropped. static void on_read_request_done_locked(void* arg, grpc_error_handle error) { proxy_connection* conn = static_cast(arg); - gpr_log(GPR_DEBUG, "on_read_request_done: %p %s", conn, - grpc_core::StatusToString(error).c_str()); + VLOG(2) << "on_read_request_done: " << conn << " " + << grpc_core::StatusToString(error); if (!error.ok()) { proxy_connection_failed(conn, SETUP_FAILED, "HTTP proxy read request", error); @@ -670,7 +670,7 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); proxy->proxy_name = grpc_core::JoinHostPort("localhost", proxy_port); - gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.c_str()); + LOG(INFO) << "Proxy address: " << proxy->proxy_name; // Create TCP server. auto channel_args = grpc_core::CoreConfiguration::Get() .channel_args_preconditioning() diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index cb1a2e04cb2..febdb809838 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -31,7 +32,6 @@ #include #include #include -#include #include #include @@ -106,8 +106,8 @@ grpc_end2end_proxy* grpc_end2end_proxy_create( proxy->proxy_port = grpc_core::JoinHostPort("localhost", proxy_port); proxy->server_port = grpc_core::JoinHostPort("localhost", server_port); - gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port.c_str(), - proxy->server_port.c_str()); + VLOG(2) << "PROXY ADDR:" << proxy->proxy_port + << " BACKEND:" << proxy->server_port; proxy->cq = grpc_completion_queue_create_for_next(nullptr); proxy->server = def->create_server(proxy->proxy_port.c_str(), server_args); diff --git a/test/core/end2end/fuzzers/BUILD b/test/core/end2end/fuzzers/BUILD index 35f52f6be3b..c3a1f0245c9 100644 --- a/test/core/end2end/fuzzers/BUILD +++ b/test/core/end2end/fuzzers/BUILD @@ -36,6 +36,7 @@ grpc_cc_library( hdrs = ["fuzzing_common.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -92,6 +93,7 @@ grpc_cc_library( name = "network_input", srcs = ["network_input.cc"], hdrs = ["network_input.h"], + external_deps = ["absl/log:log"], deps = [ "fuzzer_input_proto", "//:chttp2_frame", diff --git a/test/core/end2end/fuzzers/fuzzing_common.cc b/test/core/end2end/fuzzers/fuzzing_common.cc index 4a20a7870fe..2597694bf3b 100644 --- a/test/core/end2end/fuzzers/fuzzing_common.cc +++ b/test/core/end2end/fuzzers/fuzzing_common.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/types/optional.h" @@ -638,7 +639,7 @@ bool BasicFuzzer::Continue() { BasicFuzzer::Result BasicFuzzer::ExecuteAction( const api_fuzzer::Action& action) { - gpr_log(GPR_DEBUG, "EXECUTE_ACTION: %s", action.DebugString().c_str()); + VLOG(2) << "EXECUTE_ACTION: " << action.DebugString(); switch (action.type_case()) { case api_fuzzer::Action::TYPE_NOT_SET: return BasicFuzzer::Result::kFailed; diff --git a/test/core/end2end/fuzzers/network_input.cc b/test/core/end2end/fuzzers/network_input.cc index 855d3185678..278fd0ffc69 100644 --- a/test/core/end2end/fuzzers/network_input.cc +++ b/test/core/end2end/fuzzers/network_input.cc @@ -23,6 +23,7 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" @@ -520,8 +521,7 @@ Duration ScheduleConnection( endpoint) mutable { ExecCtx exec_ctx; if (!endpoint.ok()) { - gpr_log(GPR_ERROR, "Failed to connect: %s", - endpoint.status().ToString().c_str()); + LOG(ERROR) << "Failed to connect: " << endpoint.status(); return; } std::shared_ptr ep = diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 3efd3939364..edf58074223 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -27,6 +27,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" @@ -40,7 +41,6 @@ #include #include #include -#include #include #include @@ -212,9 +212,8 @@ static void my_cancel_ares_request(grpc_ares_request* request) { int main(int argc, char** argv) { // TODO(yijiem): rewrite this test with a custom EventEngine DNS Resolver if (grpc_core::IsEventEngineDnsEnabled()) { - gpr_log( - GPR_ERROR, - "Skipping iomgr-specific DNS test because EventEngine DNS is enabled"); + LOG(ERROR) << "Skipping iomgr-specific DNS test because EventEngine DNS is " + "enabled"; return 0; } grpc_completion_queue* cq; diff --git a/test/core/end2end/grpc_core_end2end_test.bzl b/test/core/end2end/grpc_core_end2end_test.bzl index 78733efcf2b..8b75ae6aac8 100644 --- a/test/core/end2end/grpc_core_end2end_test.bzl +++ b/test/core/end2end/grpc_core_end2end_test.bzl @@ -43,6 +43,9 @@ def grpc_core_end2end_test(name, shard_count = 10, tags = []): srcs = [ "tests/%s.cc" % name, ], + external_deps = [ + "absl/log:log", + ], deps = [ "cq_verifier", "end2end_test_lib", diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index d24c6956235..3d1470194ec 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,6 +25,7 @@ #include "absl/functional/any_invocable.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/types/optional.h" #include "gtest/gtest.h" @@ -37,7 +38,6 @@ #include #include #include -#include #include #include "src/core/lib/channel/channel_args.h" @@ -245,9 +245,7 @@ static void simple_request_body(grpc_core::CoreTestFixture* f, class H2SslCertTest : public ::testing::TestWithParam { protected: - H2SslCertTest() { - gpr_log(GPR_INFO, "SSL_CERT_tests/%s", GetParam().config.name); - } + H2SslCertTest() { LOG(INFO) << "SSL_CERT_tests/" << GetParam().config.name; } void SetUp() override { fixture_ = GetParam().config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs()); diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index a297eb61a3b..1f086c3f98a 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include #include @@ -155,7 +155,7 @@ static void cleanup_test() { } static void test_non_null_reserved_on_start_batch() { - gpr_log(GPR_INFO, "test_non_null_reserved_on_start_batch"); + LOG(INFO) << "test_non_null_reserved_on_start_batch"; prepare_test(1); CHECK(GRPC_CALL_ERROR == @@ -165,7 +165,7 @@ static void test_non_null_reserved_on_start_batch() { } static void test_non_null_reserved_on_op() { - gpr_log(GPR_INFO, "test_non_null_reserved_on_op"); + LOG(INFO) << "test_non_null_reserved_on_op"; grpc_op* op; prepare_test(1); @@ -184,7 +184,7 @@ static void test_non_null_reserved_on_op() { } static void test_send_initial_metadata_more_than_once() { - gpr_log(GPR_INFO, "test_send_initial_metadata_more_than_once"); + LOG(INFO) << "test_send_initial_metadata_more_than_once"; grpc_op* op; prepare_test(1); @@ -216,7 +216,7 @@ static void test_send_initial_metadata_more_than_once() { } static void test_too_many_metadata() { - gpr_log(GPR_INFO, "test_too_many_metadata"); + LOG(INFO) << "test_too_many_metadata"; grpc_op* op; prepare_test(1); @@ -235,7 +235,7 @@ static void test_too_many_metadata() { } static void test_send_null_message() { - gpr_log(GPR_INFO, "test_send_null_message"); + LOG(INFO) << "test_send_null_message"; grpc_op* op; prepare_test(1); @@ -259,7 +259,7 @@ static void test_send_null_message() { } static void test_send_messages_at_the_same_time() { - gpr_log(GPR_INFO, "test_send_messages_at_the_same_time"); + LOG(INFO) << "test_send_messages_at_the_same_time"; grpc_op* op; grpc_slice request_payload_slice = @@ -293,7 +293,7 @@ static void test_send_messages_at_the_same_time() { } static void test_send_server_status_from_client() { - gpr_log(GPR_INFO, "test_send_server_status_from_client"); + LOG(INFO) << "test_send_server_status_from_client"; grpc_op* op; prepare_test(1); @@ -315,7 +315,7 @@ static void test_send_server_status_from_client() { } static void test_receive_initial_metadata_twice_at_client() { - gpr_log(GPR_INFO, "test_receive_initial_metadata_twice_at_client"); + LOG(INFO) << "test_receive_initial_metadata_twice_at_client"; grpc_op* op; prepare_test(1); @@ -347,7 +347,7 @@ static void test_receive_initial_metadata_twice_at_client() { } static void test_receive_message_with_invalid_flags() { - gpr_log(GPR_INFO, "test_receive_message_with_invalid_flags"); + LOG(INFO) << "test_receive_message_with_invalid_flags"; grpc_op* op; grpc_byte_buffer* payload = nullptr; @@ -366,7 +366,7 @@ static void test_receive_message_with_invalid_flags() { } static void test_receive_two_messages_at_the_same_time() { - gpr_log(GPR_INFO, "test_receive_two_messages_at_the_same_time"); + LOG(INFO) << "test_receive_two_messages_at_the_same_time"; grpc_op* op; grpc_byte_buffer* payload = nullptr; @@ -390,7 +390,7 @@ static void test_receive_two_messages_at_the_same_time() { } static void test_recv_close_on_server_from_client() { - gpr_log(GPR_INFO, "test_recv_close_on_server_from_client"); + LOG(INFO) << "test_recv_close_on_server_from_client"; grpc_op* op; prepare_test(1); @@ -409,7 +409,7 @@ static void test_recv_close_on_server_from_client() { } static void test_recv_status_on_client_twice() { - gpr_log(GPR_INFO, "test_recv_status_on_client_twice"); + LOG(INFO) << "test_recv_status_on_client_twice"; grpc_op* op; prepare_test(1); @@ -446,7 +446,7 @@ static void test_recv_status_on_client_twice() { } static void test_send_close_from_client_on_server() { - gpr_log(GPR_INFO, "test_send_close_from_client_on_server"); + LOG(INFO) << "test_send_close_from_client_on_server"; grpc_op* op; prepare_test(0); @@ -464,7 +464,7 @@ static void test_send_close_from_client_on_server() { } static void test_recv_status_on_client_from_server() { - gpr_log(GPR_INFO, "test_recv_status_on_client_from_server"); + LOG(INFO) << "test_recv_status_on_client_from_server"; grpc_op* op; prepare_test(0); @@ -486,7 +486,7 @@ static void test_recv_status_on_client_from_server() { } static void test_send_status_from_server_with_invalid_flags() { - gpr_log(GPR_INFO, "test_send_status_from_server_with_invalid_flags"); + LOG(INFO) << "test_send_status_from_server_with_invalid_flags"; grpc_op* op; prepare_test(0); @@ -508,7 +508,7 @@ static void test_send_status_from_server_with_invalid_flags() { } static void test_too_many_trailing_metadata() { - gpr_log(GPR_INFO, "test_too_many_trailing_metadata"); + LOG(INFO) << "test_too_many_trailing_metadata"; grpc_op* op; prepare_test(0); @@ -531,7 +531,7 @@ static void test_too_many_trailing_metadata() { } static void test_send_server_status_twice() { - gpr_log(GPR_INFO, "test_send_server_status_twice"); + LOG(INFO) << "test_send_server_status_twice"; grpc_op* op; prepare_test(0); @@ -560,7 +560,7 @@ static void test_send_server_status_twice() { } static void test_recv_close_on_server_with_invalid_flags() { - gpr_log(GPR_INFO, "test_recv_close_on_server_with_invalid_flags"); + LOG(INFO) << "test_recv_close_on_server_with_invalid_flags"; grpc_op* op; prepare_test(0); @@ -579,7 +579,7 @@ static void test_recv_close_on_server_with_invalid_flags() { } static void test_recv_close_on_server_twice() { - gpr_log(GPR_INFO, "test_recv_close_on_server_twice"); + LOG(INFO) << "test_recv_close_on_server_twice"; grpc_op* op; prepare_test(0); @@ -603,7 +603,7 @@ static void test_recv_close_on_server_twice() { } static void test_invalid_initial_metadata_reserved_key() { - gpr_log(GPR_INFO, "test_invalid_initial_metadata_reserved_key"); + LOG(INFO) << "test_invalid_initial_metadata_reserved_key"; grpc_metadata metadata; metadata.key = grpc_slice_from_static_string(":start_with_colon"); @@ -626,7 +626,7 @@ static void test_invalid_initial_metadata_reserved_key() { } static void test_multiple_ops_in_a_single_batch() { - gpr_log(GPR_INFO, "test_multiple_ops_in_a_single_batch"); + LOG(INFO) << "test_multiple_ops_in_a_single_batch"; grpc_op* op; prepare_test(1); diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index dc3db4b37bf..4b14f0a1a72 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/time/time.h" @@ -31,7 +32,6 @@ #include #include #include -#include #include #include "src/core/lib/channel/channel_args.h" @@ -45,7 +45,7 @@ #include "test/core/test_util/test_config.h" void run_test(bool wait_for_ready) { - gpr_log(GPR_INFO, "TEST: wait_for_ready=%d", wait_for_ready); + LOG(INFO) << "TEST: wait_for_ready=" << wait_for_ready; grpc_init(); @@ -104,7 +104,7 @@ void run_test(bool wait_for_ready) { cqv.Expect(grpc_core::CqVerifier::tag(1), true); cqv.Verify(); - gpr_log(GPR_INFO, "call status: %d", status); + LOG(INFO) << "call status: " << status; if (wait_for_ready) { CHECK_EQ(status, GRPC_STATUS_DEADLINE_EXCEEDED); } else { diff --git a/test/core/end2end/tests/call_creds.cc b/test/core/end2end/tests/call_creds.cc index ce6b949085f..2b078a1152d 100644 --- a/test/core/end2end/tests/call_creds.cc +++ b/test/core/end2end/tests/call_creds.cc @@ -18,6 +18,7 @@ #include +#include "absl/log/log.h" #include "absl/types/optional.h" #include "gtest/gtest.h" @@ -25,7 +26,6 @@ #include #include #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/time.h" @@ -47,17 +47,17 @@ const char overridden_fake_md_value[] = "overridden_fake_value"; void PrintAuthContext(bool is_client, const grpc_auth_context* ctx) { const grpc_auth_property* p; grpc_auth_property_iterator it; - gpr_log(GPR_INFO, "%s peer:", is_client ? "client" : "server"); - gpr_log(GPR_INFO, "\tauthenticated: %s", - grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO"); + LOG(INFO) << (is_client ? "client" : "server") << " peer:"; + LOG(INFO) << "\tauthenticated: " + << (grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO"); it = grpc_auth_context_peer_identity(ctx); while ((p = grpc_auth_property_iterator_next(&it)) != nullptr) { - gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); + LOG(INFO) << "\t\t" << p->name << ": " << p->value; } - gpr_log(GPR_INFO, "\tall properties:"); + LOG(INFO) << "\tall properties:"; it = grpc_auth_context_property_iterator(ctx); while ((p = grpc_auth_property_iterator_next(&it)) != nullptr) { - gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); + LOG(INFO) << "\t\t" << p->name << ": " << p->value; } } diff --git a/test/core/end2end/tests/disappearing_server.cc b/test/core/end2end/tests/disappearing_server.cc index 81cea5a5ad2..5b65e20eb57 100644 --- a/test/core/end2end/tests/disappearing_server.cc +++ b/test/core/end2end/tests/disappearing_server.cc @@ -18,10 +18,10 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/time.h" @@ -31,13 +31,13 @@ namespace grpc_core { static void OneRequestAndShutdownServer(CoreEnd2endTest& test) { - gpr_log(GPR_ERROR, "Create client side call"); + LOG(ERROR) << "Create client side call"; auto c = test.NewClientCall("/service/method") .Timeout(Duration::Seconds(30)) .Create(); CoreEnd2endTest::IncomingMetadata server_initial_md; CoreEnd2endTest::IncomingStatusOnClient server_status; - gpr_log(GPR_ERROR, "Start initial batch"); + LOG(ERROR) << "Start initial batch"; c.NewBatch(1) .SendInitialMetadata({}) .SendCloseFromClient() diff --git a/test/core/end2end/tests/filter_context.cc b/test/core/end2end/tests/filter_context.cc index b3e2759ef1f..789a05d94d7 100644 --- a/test/core/end2end/tests/filter_context.cc +++ b/test/core/end2end/tests/filter_context.cc @@ -20,11 +20,11 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/channel/channel_fwd.h" #include "src/core/lib/channel/channel_stack.h" @@ -53,7 +53,7 @@ grpc_error_handle init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { call_data* calld = static_cast(elem->call_data); calld->context = args->context; - gpr_log(GPR_INFO, "init_call_elem(): context=%p", args->context); + LOG(INFO) << "init_call_elem(): context=" << args->context; return absl::OkStatus(); } @@ -63,8 +63,8 @@ void start_transport_stream_op_batch(grpc_call_element* elem, // If batch payload context is not null (which will happen in some // cancellation cases), make sure we get the same context here that we // saw in init_call_elem(). - gpr_log(GPR_INFO, "start_transport_stream_op_batch(): context=%p", - batch->payload->context); + LOG(INFO) << "start_transport_stream_op_batch(): context=" + << batch->payload->context; if (batch->payload->context != nullptr) { CHECK(calld->context == batch->payload->context); } diff --git a/test/core/end2end/tests/resource_quota_server.cc b/test/core/end2end/tests/resource_quota_server.cc index acf4c109089..0bc7a69e034 100644 --- a/test/core/end2end/tests/resource_quota_server.cc +++ b/test/core/end2end/tests/resource_quota_server.cc @@ -21,13 +21,13 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/str_format.h" #include "gtest/gtest.h" #include #include #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/experiments/experiments.h" @@ -146,11 +146,11 @@ CORE_END2END_TEST(ResourceQuotaTest, ResourceQuota) { cancelled_calls_on_server++; } } - gpr_log(GPR_INFO, - "Done. %d total calls: %d cancelled at server, %d cancelled at " - "client, %d timed out, %d unavailable.", - kNumCalls, cancelled_calls_on_server, cancelled_calls_on_client, - deadline_exceeded, unavailable); + LOG(INFO) << "Done. " << kNumCalls + << " total calls: " << cancelled_calls_on_server + << " cancelled at server, " << cancelled_calls_on_client + << " cancelled at client, " << deadline_exceeded << " timed out, " + << unavailable << " unavailable."; ShutdownServerAndNotify(0); Expect(0, PerformAction{[this](bool success) { diff --git a/test/core/end2end/tests/server_streaming.cc b/test/core/end2end/tests/server_streaming.cc index 76cd2ae7382..b6fd6f30511 100644 --- a/test/core/end2end/tests/server_streaming.cc +++ b/test/core/end2end/tests/server_streaming.cc @@ -19,10 +19,10 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/gprpp/time.h" #include "test/core/end2end/cq_verifier.h" @@ -70,7 +70,7 @@ void ServerStreaming(CoreEnd2endTest& test, int num_messages) { test.Expect(104, true); test.Step(); - gpr_log(GPR_DEBUG, "SEEN_STATUS:%d", seen_status); + VLOG(2) << "SEEN_STATUS:" << seen_status; // Client keeps reading messages till it gets the status int num_messages_received = 0; diff --git a/test/core/end2end/tests/simple_delayed_request.cc b/test/core/end2end/tests/simple_delayed_request.cc index e22ea978335..bbdfe4ab790 100644 --- a/test/core/end2end/tests/simple_delayed_request.cc +++ b/test/core/end2end/tests/simple_delayed_request.cc @@ -18,12 +18,12 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include #include #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/time.h" @@ -37,17 +37,17 @@ CORE_END2END_TEST(Http2SingleHopTest, SimpleDelayedRequestShort) { .Set(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000) .Set(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 1000) .Set(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 5000)); - gpr_log(GPR_ERROR, "Create client side call"); + LOG(ERROR) << "Create client side call"; auto c = NewClientCall("/foo").Timeout(Duration::Minutes(1)).Create(); IncomingMetadata server_initial_metadata; IncomingStatusOnClient server_status; - gpr_log(GPR_ERROR, "Start initial batch"); + LOG(ERROR) << "Start initial batch"; c.NewBatch(1) .SendInitialMetadata({}, GRPC_INITIAL_METADATA_WAIT_FOR_READY) .SendCloseFromClient() .RecvInitialMetadata(server_initial_metadata) .RecvStatusOnClient(server_status); - gpr_log(GPR_ERROR, "Start server"); + LOG(ERROR) << "Start server"; InitServer(ChannelArgs()); auto s = RequestCall(101); Expect(101, true); diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc index 359489f6c2d..1e39734d327 100644 --- a/test/core/end2end/tests/simple_request.cc +++ b/test/core/end2end/tests/simple_request.cc @@ -22,13 +22,13 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/match.h" #include "absl/types/optional.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/stats_data.h" @@ -91,7 +91,7 @@ void SimpleRequestBody(CoreEnd2endTest& test) { expected_calls *= 2; } auto after = global_stats().Collect(); - gpr_log(GPR_DEBUG, "%s", StatsAsJson(after.get()).c_str()); + VLOG(2) << StatsAsJson(after.get()); EXPECT_EQ(after->client_calls_created - before->client_calls_created, expected_calls); EXPECT_EQ(after->server_calls_created - before->server_calls_created, diff --git a/test/core/end2end/tests/timeout_before_request_call.cc b/test/core/end2end/tests/timeout_before_request_call.cc index 5ad6a9872a1..bb61acd648e 100644 --- a/test/core/end2end/tests/timeout_before_request_call.cc +++ b/test/core/end2end/tests/timeout_before_request_call.cc @@ -16,6 +16,7 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include @@ -147,7 +148,7 @@ CORE_END2END_TEST(CoreDeadlineSingleHopTest, bool got_call = false; std::unique_ptr client_close; Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) { - gpr_log(GPR_INFO, "\n***\n*** got call: %d\n***", ok); + LOG(INFO) << "\n***\n*** got call: " << ok << "\n***"; got_call = true; if (ok) { // If we successfully get a call, then we should additionally get a From 989268253ee500c72848645dd5233653e0a635eb Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Sat, 11 May 2024 00:53:18 -0700 Subject: [PATCH 25/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36580) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. `#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO` Which means passing explicit parameters to gpr_info will over-ride the file name and line number of the call site. The right replacement API for this is `LOG(INFO).AtLocation(absl::string_view file, int line) << ... ` Closes #36580 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36580 from tanvi-jagtap:large_seq_state_tjagtap 8f6dd756c62434b13d9f0a90150934a3677c4e81 PiperOrigin-RevId: 632721079 --- src/core/lib/promise/detail/seq_state.h | 711 ++++++++++++------------ 1 file changed, 342 insertions(+), 369 deletions(-) diff --git a/src/core/lib/promise/detail/seq_state.h b/src/core/lib/promise/detail/seq_state.h index 3e69e60b741..841cd6cb042 100644 --- a/src/core/lib/promise/detail/seq_state.h +++ b/src/core/lib/promise/detail/seq_state.h @@ -23,6 +23,7 @@ #include "absl/base/attributes.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include @@ -144,22 +145,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/2", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/2"; } auto result = prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/2 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/2 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -177,14 +177,14 @@ struct SeqState { default: case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/2", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/2"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/2 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/2 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -287,22 +287,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/3", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/3"; } auto result = prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/3 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/3 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -319,22 +318,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/3", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/3"; } auto result = prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/3 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/3 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -352,14 +350,14 @@ struct SeqState { default: case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/3", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/3"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/3 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/3 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -489,22 +487,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/4"; } auto result = prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/4 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/4 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -521,22 +518,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/4"; } auto result = prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/4 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/4 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -553,22 +549,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/4"; } auto result = prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/4 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/4 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -586,14 +581,14 @@ struct SeqState { default: case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/4"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/4 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/4 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -751,22 +746,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/5"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/5 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -783,22 +777,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/5"; } auto result = prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/5 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -815,22 +808,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/5"; } auto result = prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/5 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -847,22 +839,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/5"; } auto result = prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/5 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -880,14 +871,14 @@ struct SeqState { default: case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/5"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/5 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/5 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -1082,22 +1073,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/6"; } auto result = prior.prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/6 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -1115,22 +1105,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/6"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/6 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -1147,22 +1136,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/6"; } auto result = prior.prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/6 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -1179,22 +1167,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/6"; } auto result = prior.prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/6 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -1211,22 +1198,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/6"; } auto result = prior.current_promise(); PromiseResult4* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits4::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits4::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/6 gets " + << (p != nullptr + ? (PromiseResultTraits4::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits4::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits4::IsOk(*p)) { @@ -1249,9 +1235,9 @@ struct SeqState { } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 6/6 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 6/6 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -1478,22 +1464,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/7"; } auto result = prior.prior.prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/7 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -1511,22 +1496,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/7"; } auto result = prior.prior.prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/7 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -1544,22 +1528,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/7"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/7 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -1576,22 +1559,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/7"; } auto result = prior.prior.prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/7 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -1608,22 +1590,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/7"; } auto result = prior.prior.current_promise(); PromiseResult4* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits4::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits4::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/7 gets " + << (p != nullptr + ? (PromiseResultTraits4::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits4::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits4::IsOk(*p)) { @@ -1640,22 +1621,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState5: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 6/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 6/7"; } auto result = prior.current_promise(); PromiseResult5* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 6/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits5::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits5::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 6/7 gets " + << (p != nullptr + ? (PromiseResultTraits5::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits5::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits5::IsOk(*p)) { @@ -1673,14 +1653,14 @@ struct SeqState { default: case State::kState6: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 7/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 7/7"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 7/7 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 7/7 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -1940,23 +1920,22 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/8"; } auto result = prior.prior.prior.prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/8 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -1975,22 +1954,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/8"; } auto result = prior.prior.prior.prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/8 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -2008,22 +1986,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/8"; } auto result = prior.prior.prior.prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/8 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -2041,22 +2018,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/8"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/8 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -2073,22 +2049,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/8"; } auto result = prior.prior.prior.current_promise(); PromiseResult4* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits4::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits4::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/8 gets " + << (p != nullptr + ? (PromiseResultTraits4::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits4::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits4::IsOk(*p)) { @@ -2105,22 +2080,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState5: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 6/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 6/8"; } auto result = prior.prior.current_promise(); PromiseResult5* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 6/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits5::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits5::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 6/8 gets " + << (p != nullptr + ? (PromiseResultTraits5::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits5::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits5::IsOk(*p)) { @@ -2137,22 +2111,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState6: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 7/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 7/8"; } auto result = prior.current_promise(); PromiseResult6* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 7/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits6::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits6::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 7/8 gets " + << (p != nullptr + ? (PromiseResultTraits6::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits6::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits6::IsOk(*p)) { @@ -2170,14 +2143,14 @@ struct SeqState { default: case State::kState7: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 8/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 8/8"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 8/8 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 8/8 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; From 06b097691e08851bd63c23dba5b538738187129a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sun, 12 May 2024 10:54:15 -0700 Subject: [PATCH 26/33] [logging] Add a helper to drop a list of variables out in a LOG statement (#36554) Not the fastest implementation possible, but it's a log helper so I'm not particularly fussed either -- but a useful utility that we can iterate on later to help debugging. Closes #36554 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36554 from ctiller:args 33b4802fccb1a667ab81c1e2b2e1c5a55c993119 PiperOrigin-RevId: 632997320 --- CMakeLists.txt | 36 +++++++++++++++ build_autogenerated.yaml | 14 ++++++ src/core/BUILD | 19 ++++++++ src/core/lib/gprpp/dump_args.cc | 54 ++++++++++++++++++++++ src/core/lib/gprpp/dump_args.h | 69 ++++++++++++++++++++++++++++ test/core/gprpp/BUILD | 14 ++++++ test/core/gprpp/dump_args_test.cc | 44 ++++++++++++++++++ tools/distrib/fix_build_deps.py | 9 ++-- tools/run_tests/generated/tests.json | 24 ++++++++++ 9 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 src/core/lib/gprpp/dump_args.cc create mode 100644 src/core/lib/gprpp/dump_args.h create mode 100644 test/core/gprpp/dump_args_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 449d17ec767..1b107dddb0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1052,6 +1052,7 @@ if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx dualstack_socket_test) endif() + add_dependencies(buildtests_cxx dump_args_test) add_dependencies(buildtests_cxx duplicate_header_bad_client_test) add_dependencies(buildtests_cxx empty_batch_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) @@ -12390,6 +12391,41 @@ endif() endif() if(gRPC_BUILD_TESTS) +add_executable(dump_args_test + src/core/lib/gprpp/dump_args.cc + test/core/gprpp/dump_args_test.cc +) +target_compile_features(dump_args_test PUBLIC cxx_std_14) +target_include_directories(dump_args_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(dump_args_test + ${_gRPC_ALLTARGETS_LIBRARIES} + gtest + absl::any_invocable + absl::check +) + + +endif() +if(gRPC_BUILD_TESTS) + add_executable(duplicate_header_bad_client_test test/core/bad_client/bad_client.cc test/core/bad_client/tests/duplicate_header.cc diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index d15f905f347..7458cc04b7f 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -8661,6 +8661,20 @@ targets: - linux - posix - mac +- name: dump_args_test + gtest: true + build: test + language: c++ + headers: + - src/core/lib/gprpp/dump_args.h + src: + - src/core/lib/gprpp/dump_args.cc + - test/core/gprpp/dump_args_test.cc + deps: + - gtest + - absl/functional:any_invocable + - absl/log:check + uses_polling: false - name: duplicate_header_bad_client_test gtest: true build: test diff --git a/src/core/BUILD b/src/core/BUILD index 87225db6d7c..b15bf14f933 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -48,6 +48,25 @@ grpc_cc_library( language = "c++", ) +grpc_cc_library( + name = "dump_args", + srcs = [ + "lib/gprpp/dump_args.cc", + ], + hdrs = [ + "lib/gprpp/dump_args.h", + ], + external_deps = [ + "absl/functional:any_invocable", + "absl/log:check", + "absl/strings", + ], + language = "c++", + deps = [ + "//:gpr_platform", + ], +) + grpc_cc_library( name = "slice_cast", hdrs = [ diff --git a/src/core/lib/gprpp/dump_args.cc b/src/core/lib/gprpp/dump_args.cc new file mode 100644 index 00000000000..e5bc183246b --- /dev/null +++ b/src/core/lib/gprpp/dump_args.cc @@ -0,0 +1,54 @@ +// Copyright 2024 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/core/lib/gprpp/dump_args.h" + +#include "absl/log/check.h" +#include "absl/strings/ascii.h" +#include "absl/strings/string_view.h" + +namespace grpc_core { +namespace dump_args_detail { + +std::ostream& operator<<(std::ostream& out, const DumpArgs& args) { + // Parse the argument string into a vector of keys. + // #__VA_ARGS__ produces a stringified version of the arguments passed to the + // macro. It's comma separated, and we can use that to split the string into + // keys. Those keys might include parenthesis for e.g. argument lists, and so + // we need to skip commas that are inside parenthesis. + std::vector keys; + int depth = 0; + const char* start = args.arg_string_; + for (const char* p = args.arg_string_; *p; ++p) { + if (*p == '(') { + ++depth; + } else if (*p == ')') { + --depth; + } else if (*p == ',' && depth == 0) { + keys.push_back(absl::string_view(start, p - start)); + start = p + 1; + } + } + keys.push_back(start); + CHECK_EQ(keys.size(), args.arg_dumpers_.size()); + for (size_t i = 0; i < keys.size(); i++) { + if (i != 0) out << ", "; + out << absl::StripAsciiWhitespace(keys[i]) << " = "; + args.arg_dumpers_[i](out); + } + return out; +} + +} // namespace dump_args_detail +} // namespace grpc_core \ No newline at end of file diff --git a/src/core/lib/gprpp/dump_args.h b/src/core/lib/gprpp/dump_args.h new file mode 100644 index 00000000000..c2b66ce2be3 --- /dev/null +++ b/src/core/lib/gprpp/dump_args.h @@ -0,0 +1,69 @@ +// Copyright 2024 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_SRC_CORE_LIB_GPRPP_DUMP_ARGS_H +#define GRPC_SRC_CORE_LIB_GPRPP_DUMP_ARGS_H + +#include +#include + +#include "absl/functional/any_invocable.h" + +namespace grpc_core { +namespace dump_args_detail { + +// Helper function... just ignore the initializer list passed into it. +// Allows doing 'statements' via parameter pack expansion in C++11 - given +// template : +// do_these_things({foo()...}); +// will execute foo() for each T in Ts. +template +void do_these_things(std::initializer_list) {} + +class DumpArgs { + public: + template + explicit DumpArgs(const char* arg_string, const Args&... args) + : arg_string_(arg_string) { + do_these_things( + {AddDumper([a = &args](std::ostream& os) { os << *a; })...}); + } + + friend std::ostream& operator<<(std::ostream& out, const DumpArgs& args); + + private: + int AddDumper(absl::AnyInvocable dumper) { + arg_dumpers_.push_back(std::move(dumper)); + return 0; + } + + const char* arg_string_; + std::vector> arg_dumpers_; +}; + +} // namespace dump_args_detail +} // namespace grpc_core + +// Helper to print a list of variables and their values. +// Each type must be streamable to std::ostream. +// Usage: +// int a = 1; +// int b = 2; +// LOG(INFO) << GRPC_DUMP_ARGS(a, b) +// Output: +// a = 1, b = 2 +#define GRPC_DUMP_ARGS(...) \ + grpc_core::dump_args_detail::DumpArgs(#__VA_ARGS__, __VA_ARGS__) + +#endif // GRPC_SRC_CORE_LIB_GPRPP_DUMP_ARGS_H diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index b6ca769f46d..177c5809b0c 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -60,6 +60,20 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "dump_args_test", + srcs = ["dump_args_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + uses_event_engine = False, + uses_polling = False, + deps = [ + "//src/core:dump_args", + ], +) + # TODO(hork): solidify fork support requirements for EventEngines grpc_cc_test( name = "fork_test", diff --git a/test/core/gprpp/dump_args_test.cc b/test/core/gprpp/dump_args_test.cc new file mode 100644 index 00000000000..2207d4eab62 --- /dev/null +++ b/test/core/gprpp/dump_args_test.cc @@ -0,0 +1,44 @@ +// Copyright 2024 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/core/lib/gprpp/dump_args.h" + +#include + +#include "gtest/gtest.h" + +template +std::string Stringify(const T& t) { + std::ostringstream oss; + oss << t; + return oss.str(); +} + +int add(int a, int b) { return a + b; } + +TEST(DumpArgsTest, Basic) { + int a = 1; + int b = 2; + int c = 3; + EXPECT_EQ("a = 1, b = 2, c = 3", Stringify(GRPC_DUMP_ARGS(a, b, c))); +} + +TEST(DumpArgsTest, FunctionCall) { + EXPECT_EQ("add(1, 2) = 3", Stringify(GRPC_DUMP_ARGS(add(1, 2)))); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tools/distrib/fix_build_deps.py b/tools/distrib/fix_build_deps.py index 03dbcc9137b..0a114910e3e 100755 --- a/tools/distrib/fix_build_deps.py +++ b/tools/distrib/fix_build_deps.py @@ -64,6 +64,7 @@ EXTERNAL_DEPS = { "absl/functional/bind_front.h": "absl/functional:bind_front", "absl/functional/function_ref.h": "absl/functional:function_ref", "absl/hash/hash.h": "absl/hash", + "absl/log/check.h": "absl/log:check", "absl/memory/memory.h": "absl/memory", "absl/meta/type_traits.h": "absl/meta:type_traits", "absl/numeric/int128.h": "absl/numeric:int128", @@ -543,9 +544,11 @@ def make_library(library): # once EventEngine lands we can clean this up deps = Choices( library, - {"//:grpc_base": ["//:grpc", "//:grpc_unsecure"]} - if library.startswith("//test/") - else {}, + ( + {"//:grpc_base": ["//:grpc", "//:grpc_unsecure"]} + if library.startswith("//test/") + else {} + ), ) external_deps = Choices(None, {}) for hdr in hdrs: diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 61b98ca9bd1..a733817a370 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2969,6 +2969,30 @@ ], "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": "dump_args_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From 5a99b7ea827ad5acefea363ddd54c6a0fa05c91b Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Sun, 12 May 2024 20:10:52 -0700 Subject: [PATCH 27/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log (#36585) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - gpr_log In this CL we are migrating from gRPCs own gpr logging mechanism to absl logging mechanism. The intention is to deprecate gpr_log in the future. We have the following mapping 1. gpr_log(GPR_INFO,...) -> LOG(INFO) 2. gpr_log(GPR_ERROR,...) -> LOG(ERROR) 3. gpr_log(GPR_DEBUG,...) -> VLOG(2) Reviewers need to check : 1. If the above mapping is correct. 2. The content of the log is as before. gpr_log format strings did not use string_view or std::string . absl LOG accepts these. So there will be some elimination of string_view and std::string related conversions. This is expected. Closes #36585 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36585 from tanvi-jagtap:large_file_regex_conv 2ca173855a9de7b3d4865d6528221d1d7c6cda58 PiperOrigin-RevId: 633069869 --- .../binder/transport/binder_transport.cc | 29 +++++---- .../binder/wire_format/wire_reader_impl.cc | 21 +++--- .../chttp2/transport/chttp2_transport.cc | 3 +- src/core/lib/iomgr/ev_epoll1_linux.cc | 25 +++---- src/core/lib/iomgr/tcp_posix.cc | 27 ++++---- .../security/credentials/jwt/jwt_verifier.cc | 58 ++++++++--------- src/core/lib/surface/call.cc | 4 +- .../load_balancing/xds/xds_override_host.cc | 7 +- .../alts/handshaker/alts_tsi_handshaker.cc | 65 +++++++++---------- 9 files changed, 122 insertions(+), 117 deletions(-) diff --git a/src/core/ext/transport/binder/transport/binder_transport.cc b/src/core/ext/transport/binder/transport/binder_transport.cc index b5e32e913b7..65512675d96 100644 --- a/src/core/ext/transport/binder/transport/binder_transport.cc +++ b/src/core/ext/transport/binder/transport/binder_transport.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" @@ -141,7 +142,7 @@ static void AssignMetadata(grpc_metadata_batch* mb, static void cancel_stream_locked(grpc_binder_transport* transport, grpc_binder_stream* stream, grpc_error_handle error) { - gpr_log(GPR_INFO, "cancel_stream_locked"); + LOG(INFO) << "cancel_stream_locked"; if (!stream->is_closed) { CHECK(stream->cancel_self_error.ok()); stream->is_closed = true; @@ -200,7 +201,7 @@ static void recv_initial_metadata_locked(void* arg, CHECK(stream->recv_initial_metadata); CHECK(stream->recv_initial_metadata_ready); if (!args->initial_metadata.ok()) { - gpr_log(GPR_ERROR, "Failed to parse initial metadata"); + LOG(ERROR) << "Failed to parse initial metadata"; return absl_status_to_grpc_error(args->initial_metadata.status()); } if (!stream->is_client) { @@ -237,11 +238,11 @@ static void recv_message_locked(void* arg, grpc_error_handle /*error*/) { CHECK(stream->recv_message); CHECK(stream->recv_message_ready); if (!args->message.ok()) { - gpr_log(GPR_ERROR, "Failed to receive message"); + LOG(ERROR) << "Failed to receive message"; if (args->message.status().message() == grpc_binder::TransportStreamReceiver:: kGrpcBinderTransportCancelledGracefully) { - gpr_log(GPR_ERROR, "message cancelled gracefully"); + LOG(ERROR) << "message cancelled gracefully"; // Cancelled because we've already received trailing metadata. // It's not an error in this case. return absl::OkStatus(); @@ -281,13 +282,13 @@ static void recv_trailing_metadata_locked(void* arg, CHECK(stream->recv_trailing_metadata); CHECK(stream->recv_trailing_metadata_finished); if (!args->trailing_metadata.ok()) { - gpr_log(GPR_ERROR, "Failed to receive trailing metadata"); + LOG(ERROR) << "Failed to receive trailing metadata"; return absl_status_to_grpc_error(args->trailing_metadata.status()); } if (!stream->is_client) { // Client will not send non-empty trailing metadata. if (!args->trailing_metadata.value().empty()) { - gpr_log(GPR_ERROR, "Server receives non-empty trailing metadata."); + LOG(ERROR) << "Server receives non-empty trailing metadata."; return absl::CancelledError(); } } else { @@ -371,7 +372,7 @@ class MetadataEncoder { static void accept_stream_locked(void* gt, grpc_error_handle /*error*/) { grpc_binder_transport* transport = static_cast(gt); if (transport->accept_stream_fn) { - gpr_log(GPR_INFO, "Accepting a stream"); + LOG(INFO) << "Accepting a stream"; // must pass in a non-null value. (*transport->accept_stream_fn)(transport->accept_stream_user_data, transport, transport); @@ -449,7 +450,7 @@ static void perform_stream_op_locked(void* stream_op, std::make_unique(tx_code, transport->is_client); if (op->send_initial_metadata) { - gpr_log(GPR_INFO, "send_initial_metadata"); + LOG(INFO) << "send_initial_metadata"; grpc_binder::Metadata init_md; auto batch = op->payload->send_initial_metadata.send_initial_metadata; @@ -459,12 +460,12 @@ static void perform_stream_op_locked(void* stream_op, tx->SetPrefix(init_md); } if (op->send_message) { - gpr_log(GPR_INFO, "send_message"); + LOG(INFO) << "send_message"; tx->SetData(op->payload->send_message.send_message->JoinIntoString()); } if (op->send_trailing_metadata) { - gpr_log(GPR_INFO, "send_trailing_metadata"); + LOG(INFO) << "send_trailing_metadata"; auto batch = op->payload->send_trailing_metadata.send_trailing_metadata; grpc_binder::Metadata trailing_metadata; @@ -477,7 +478,7 @@ static void perform_stream_op_locked(void* stream_op, tx->SetSuffix(trailing_metadata); } if (op->recv_initial_metadata) { - gpr_log(GPR_INFO, "recv_initial_metadata"); + LOG(INFO) << "recv_initial_metadata"; stream->recv_initial_metadata_ready = op->payload->recv_initial_metadata.recv_initial_metadata_ready; stream->recv_initial_metadata = @@ -500,7 +501,7 @@ static void perform_stream_op_locked(void* stream_op, }); } if (op->recv_message) { - gpr_log(GPR_INFO, "recv_message"); + LOG(INFO) << "recv_message"; stream->recv_message_ready = op->payload->recv_message.recv_message_ready; stream->recv_message = op->payload->recv_message.recv_message; stream->call_failed_before_recv_message = @@ -523,7 +524,7 @@ static void perform_stream_op_locked(void* stream_op, }); } if (op->recv_trailing_metadata) { - gpr_log(GPR_INFO, "recv_trailing_metadata"); + LOG(INFO) << "recv_trailing_metadata"; stream->recv_trailing_metadata_finished = op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; stream->recv_trailing_metadata = @@ -571,7 +572,7 @@ static void perform_stream_op_locked(void* stream_op, if (op->on_complete != nullptr) { grpc_core::ExecCtx::Run(DEBUG_LOCATION, op->on_complete, absl_status_to_grpc_error(status)); - gpr_log(GPR_INFO, "on_complete closure scheduled"); + LOG(INFO) << "on_complete closure scheduled"; } GRPC_BINDER_STREAM_UNREF(stream, "perform_stream_op"); } diff --git a/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc b/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc index 8595f8bf149..02cd6cf09cd 100644 --- a/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc +++ b/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc @@ -26,6 +26,7 @@ #include "absl/functional/any_invocable.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/status/statusor.h" @@ -136,9 +137,9 @@ void WireReaderImpl::SendSetupTransport(Binder* binder) { std::unique_ptr WireReaderImpl::RecvSetupTransport() { // TODO(b/191941760): avoid blocking, handle wire_writer_noti lifetime // better - gpr_log(GPR_DEBUG, "start waiting for noti"); + VLOG(2) << "start waiting for noti"; connection_noti_.WaitForNotification(); - gpr_log(GPR_DEBUG, "end waiting for noti"); + VLOG(2) << "end waiting for noti"; return std::move(other_end_binder_); } @@ -153,8 +154,8 @@ absl::Status WireReaderImpl::ProcessTransaction(transaction_code_t code, BinderTransportTxCode::SETUP_TRANSPORT) && code <= static_cast( BinderTransportTxCode::PING_RESPONSE))) { - gpr_log(GPR_INFO, - "Received unknown control message. Shutdown transport gracefully."); + LOG(INFO) + << "Received unknown control message. Shutdown transport gracefully."; // TODO(waynetu): Shutdown transport gracefully. return absl::OkStatus(); } @@ -210,8 +211,8 @@ absl::Status WireReaderImpl::ProcessTransaction(transaction_code_t code, break; } case BinderTransportTxCode::SHUTDOWN_TRANSPORT: { - gpr_log(GPR_ERROR, - "Received SHUTDOWN_TRANSPORT request but not implemented yet."); + LOG(ERROR) + << "Received SHUTDOWN_TRANSPORT request but not implemented yet."; return absl::UnimplementedError("SHUTDOWN_TRANSPORT"); } case BinderTransportTxCode::ACKNOWLEDGE_BYTES: { @@ -286,16 +287,16 @@ absl::Status WireReaderImpl::ProcessStreamingTransaction( tx_process_result.ToString().c_str()); // Something went wrong when receiving transaction. Cancel failed requests. if (cancellation_flags & kFlagPrefix) { - gpr_log(GPR_INFO, "cancelling initial metadata"); + LOG(INFO) << "cancelling initial metadata"; transport_stream_receiver_->NotifyRecvInitialMetadata(code, tx_process_result); } if (cancellation_flags & kFlagMessageData) { - gpr_log(GPR_INFO, "cancelling message data"); + LOG(INFO) << "cancelling message data"; transport_stream_receiver_->NotifyRecvMessage(code, tx_process_result); } if (cancellation_flags & kFlagSuffix) { - gpr_log(GPR_INFO, "cancelling trailing metadata"); + LOG(INFO) << "cancelling trailing metadata"; transport_stream_receiver_->NotifyRecvTrailingMetadata( code, tx_process_result, 0); } @@ -338,7 +339,7 @@ absl::Status WireReaderImpl::ProcessStreamingTransactionImpl( // intended behavior. // TODO(waynetu): What should be returned here? if (flags == 0) { - gpr_log(GPR_INFO, "[WARNING] Receive empty transaction. Ignored."); + LOG(INFO) << "[WARNING] Receive empty transaction. Ignored."; return absl::OkStatus(); } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9a28649dd52..4acd9b51b3f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -35,6 +35,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/hash/hash.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/meta/type_traits.h" #include "absl/random/random.h" #include "absl/status/status.h" @@ -1324,7 +1325,7 @@ static bool contains_non_ok_status(grpc_metadata_batch* batch) { static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { - gpr_log(GPR_INFO, "--metadata--"); + LOG(INFO) << "--metadata--"; const std::string prefix = absl::StrCat( "HTTP:", id, is_initial ? ":HDR" : ":TRL", is_client ? ":CLI:" : ":SVR:"); md_batch->Log([&prefix](absl::string_view key, absl::string_view value) { diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index c36f3833d9f..6461b10a6cb 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -41,6 +41,7 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" @@ -100,14 +101,14 @@ static int epoll_create_and_cloexec() { #ifdef GRPC_LINUX_EPOLL_CREATE1 int fd = epoll_create1(EPOLL_CLOEXEC); if (fd < 0) { - gpr_log(GPR_ERROR, "epoll_create1 unavailable"); + LOG(ERROR) << "epoll_create1 unavailable"; } #else int fd = epoll_create(MAX_EPOLL_EVENTS); if (fd < 0) { - gpr_log(GPR_ERROR, "epoll_create unavailable"); + LOG(ERROR) << "epoll_create unavailable"; } else if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { - gpr_log(GPR_ERROR, "fcntl following epoll_create failed"); + LOG(ERROR) << "fcntl following epoll_create failed"; return -1; } #endif @@ -891,7 +892,7 @@ static bool check_neighborhood_for_available_poller( } } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. beaten to choose next poller"); + LOG(INFO) << " .. beaten to choose next poller"; } } // even if we didn't win the cas, there's a worker, we can stop @@ -990,7 +991,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, gpr_cv_destroy(&worker->cv); } if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. remove worker"); + LOG(INFO) << " .. remove worker"; } if (EMPTIED == worker_remove(pollset, worker)) { pollset_maybe_finish_shutdown(pollset); @@ -1081,7 +1082,7 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, if (root_worker == nullptr) { pollset->kicked_without_poller = true; if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kicked_without_poller"); + LOG(INFO) << " .. kicked_without_poller"; } goto done; } @@ -1146,7 +1147,7 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, } } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kicked while waking up"); + LOG(INFO) << " .. kicked while waking up"; } goto done; } @@ -1156,7 +1157,7 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, if (specific_worker->state == KICKED) { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. specific worker already kicked"); + LOG(INFO) << " .. specific worker already kicked"; } goto done; } else if (g_current_thread_worker == specific_worker) { @@ -1169,21 +1170,21 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, reinterpret_cast( gpr_atm_no_barrier_load(&g_active_poller))) { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kick active poller"); + LOG(INFO) << " .. kick active poller"; } SET_KICK_STATE(specific_worker, KICKED); ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd); goto done; } else if (specific_worker->initialized_cv) { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kick waiting worker"); + LOG(INFO) << " .. kick waiting worker"; } SET_KICK_STATE(specific_worker, KICKED); gpr_cv_signal(&specific_worker->cv); goto done; } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kick non-waiting worker"); + LOG(INFO) << " .. kick non-waiting worker"; } SET_KICK_STATE(specific_worker, KICKED); goto done; @@ -1311,7 +1312,7 @@ static void reset_event_manager_on_fork() { static bool init_epoll1_linux() { if (!g_is_shutdown) return true; if (!grpc_has_wakeup_fd()) { - gpr_log(GPR_ERROR, "Skipping epoll1 because of no wakeup fd."); + LOG(ERROR) << "Skipping epoll1 because of no wakeup fd."; return false; } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 880b10c1764..46c54c9502e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -46,6 +46,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -212,7 +213,7 @@ class TcpZerocopySendCtx { if (send_records_ == nullptr || free_send_records_ == nullptr) { gpr_free(send_records_); gpr_free(free_send_records_); - gpr_log(GPR_INFO, "Disabling TCP TX zerocopy due to memory pressure.\n"); + LOG(INFO) << "Disabling TCP TX zerocopy due to memory pressure.\n"; memory_limited_ = true; } else { for (int idx = 0; idx < max_sends_; ++idx) { @@ -836,7 +837,7 @@ static void tcp_destroy(grpc_endpoint* ep) { static void perform_reclamation(grpc_tcp* tcp) ABSL_LOCKS_EXCLUDED(tcp->read_mu) { if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "TCP: benign reclamation to free memory"); + LOG(INFO) << "TCP: benign reclamation to free memory"; } tcp->read_mu.Lock(); if (tcp->incoming_buffer != nullptr) { @@ -1294,7 +1295,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); + LOG(ERROR) << "Failed to set timestamping options on the socket."; } return false; } @@ -1380,7 +1381,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, cmsghdr* opt_stats = nullptr; if (next_cmsg == nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Received timestamp without extended error"); + LOG(ERROR) << "Received timestamp without extended error"; } return cmsg; } @@ -1392,7 +1393,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, next_cmsg = CMSG_NXTHDR(msg, opt_stats); if (next_cmsg == nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Received timestamp without extended error"); + LOG(ERROR) << "Received timestamp without extended error"; } return opt_stats; } @@ -1402,7 +1403,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, !(next_cmsg->cmsg_type == IP_RECVERR || next_cmsg->cmsg_type == IPV6_RECVERR)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Unexpected control message"); + LOG(ERROR) << "Unexpected control message"; } return cmsg; } @@ -1412,7 +1413,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); if (serr->ee_errno != ENOMSG || serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { - gpr_log(GPR_ERROR, "Unexpected control message"); + LOG(ERROR) << "Unexpected control message"; return cmsg; } tcp->tb_list.ProcessTimestamp(serr, opt_stats, tss); @@ -1462,7 +1463,7 @@ static bool process_errors(grpc_tcp* tcp) { return processed_err; } if (GPR_UNLIKELY((msg.msg_flags & MSG_CTRUNC) != 0)) { - gpr_log(GPR_ERROR, "Error message was truncated."); + LOG(ERROR) << "Error message was truncated."; } if (msg.msg_controllen == 0) { @@ -1539,14 +1540,14 @@ static bool tcp_write_with_timestamps(grpc_tcp* /*tcp*/, struct msghdr* /*msg*/, ssize_t* /*sent_length*/, int* /* saved_errno */, int /*additional_flags*/) { - gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); + LOG(ERROR) << "Write with timestamps not supported for this platform"; CHECK(0); return false; } static void tcp_handle_error(void* /*arg*/ /* grpc_tcp */, grpc_error_handle /*error*/) { - gpr_log(GPR_ERROR, "Error handling is not supported for this platform"); + LOG(ERROR) << "Error handling is not supported for this platform"; CHECK(0); } #endif // GRPC_LINUX_ERRQUEUE @@ -1842,7 +1843,7 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, : tcp_flush(tcp, &error); if (!flush_result) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "write: delayed"); + LOG(INFO) << "write: delayed"; } notify_on_write(tcp); // tcp_flush does not populate error if it has returned false. @@ -1915,7 +1916,7 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, tcp->write_cb = cb; tcp->current_zerocopy_send = zerocopy_send_record; if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "write: delayed"); + LOG(INFO) << "write: delayed"; } notify_on_write(tcp); } else { @@ -2029,7 +2030,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, if (err == 0) { tcp->tcp_zerocopy_send_ctx.set_enabled(true); } else { - gpr_log(GPR_ERROR, "Failed to set zerocopy options on the socket."); + LOG(ERROR) << "Failed to set zerocopy options on the socket."; } #endif } diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index 0e927aa075d..49cc8e21be1 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -42,6 +42,7 @@ #endif #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/escaping.h" @@ -114,7 +115,7 @@ static const EVP_MD* evp_md_from_alg(const char* alg) { static Json parse_json_part_from_jwt(const char* str, size_t len) { std::string string; if (!absl::WebSafeBase64Unescape(absl::string_view(str, len), &string)) { - gpr_log(GPR_ERROR, "Invalid base64."); + LOG(ERROR) << "Invalid base64."; return Json(); // JSON null } auto json = grpc_core::JsonParse(string); @@ -163,13 +164,13 @@ static jose_header* jose_header_from_json(Json json) { Json::Object::const_iterator it; jose_header* h = grpc_core::Zalloc(); if (json.type() != Json::Type::kObject) { - gpr_log(GPR_ERROR, "JSON value is not an object"); + LOG(ERROR) << "JSON value is not an object"; goto error; } // Check alg field. it = json.object().find("alg"); if (it == json.object().end()) { - gpr_log(GPR_ERROR, "Missing alg field."); + LOG(ERROR) << "Missing alg field."; goto error; } // We only support RSA-1.5 signatures for now. @@ -180,7 +181,7 @@ static jose_header* jose_header_from_json(Json json) { if (it->second.type() != Json::Type::kString || strncmp(alg_value, "RS", 2) != 0 || evp_md_from_alg(alg_value) == nullptr) { - gpr_log(GPR_ERROR, "Invalid alg field"); + LOG(ERROR) << "Invalid alg field"; goto error; } h->alg = alg_value; @@ -319,13 +320,13 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims* claims, skewed_now = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); if (gpr_time_cmp(skewed_now, claims->nbf) < 0) { - gpr_log(GPR_ERROR, "JWT is not valid yet."); + LOG(ERROR) << "JWT is not valid yet."; return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; } skewed_now = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); if (gpr_time_cmp(skewed_now, claims->exp) > 0) { - gpr_log(GPR_ERROR, "JWT is expired."); + LOG(ERROR) << "JWT is expired."; return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; } @@ -430,7 +431,7 @@ struct grpc_jwt_verifier { static Json json_from_http(const grpc_http_response* response) { if (response == nullptr) { - gpr_log(GPR_ERROR, "HTTP response is NULL."); + LOG(ERROR) << "HTTP response is NULL."; return Json(); // JSON null } if (response->status != 200) { @@ -441,7 +442,7 @@ static Json json_from_http(const grpc_http_response* response) { auto json = grpc_core::JsonParse( absl::string_view(response->body, response->body_length)); if (!json.ok()) { - gpr_log(GPR_ERROR, "Invalid JSON found in response."); + LOG(ERROR) << "Invalid JSON found in response."; return Json(); // JSON null } return std::move(*json); @@ -464,12 +465,12 @@ static EVP_PKEY* extract_pkey_from_x509(const char* x509_str) { BIO_write(bio, x509_str, static_cast(len)); x509 = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); if (x509 == nullptr) { - gpr_log(GPR_ERROR, "Unable to parse x509 cert."); + LOG(ERROR) << "Unable to parse x509 cert."; goto end; } result = X509_get_pubkey(x509); if (result == nullptr) { - gpr_log(GPR_ERROR, "Cannot find public key in X509 cert."); + LOG(ERROR) << "Cannot find public key in X509 cert."; } end: @@ -482,7 +483,7 @@ static BIGNUM* bignum_from_base64(const char* b64) { if (b64 == nullptr) return nullptr; std::string string; if (!absl::WebSafeBase64Unescape(b64, &string)) { - gpr_log(GPR_ERROR, "Invalid base64 for big num."); + LOG(ERROR) << "Invalid base64 for big num."; return nullptr; } return BN_bin2bn(reinterpret_cast(string.data()), @@ -540,27 +541,27 @@ static EVP_PKEY* pkey_from_jwk(const Json& json, const char* kty) { #if OPENSSL_VERSION_NUMBER < 0x30000000L rsa = RSA_new(); if (rsa == nullptr) { - gpr_log(GPR_ERROR, "Could not create rsa key."); + LOG(ERROR) << "Could not create rsa key."; goto end; } #endif it = json.object().find("n"); if (it == json.object().end()) { - gpr_log(GPR_ERROR, "Missing RSA public key field."); + LOG(ERROR) << "Missing RSA public key field."; goto end; } tmp_n = bignum_from_base64(validate_string_field(it->second, "n")); if (tmp_n == nullptr) goto end; it = json.object().find("e"); if (it == json.object().end()) { - gpr_log(GPR_ERROR, "Missing RSA public key field."); + LOG(ERROR) << "Missing RSA public key field."; goto end; } tmp_e = bignum_from_base64(validate_string_field(it->second, "e")); if (tmp_e == nullptr) goto end; #if OPENSSL_VERSION_NUMBER < 0x30000000L if (!RSA_set0_key(rsa, tmp_n, tmp_e, nullptr)) { - gpr_log(GPR_ERROR, "Cannot set RSA key from inputs."); + LOG(ERROR) << "Cannot set RSA key from inputs."; goto end; } // RSA_set0_key takes ownership on success. @@ -573,21 +574,21 @@ static EVP_PKEY* pkey_from_jwk(const Json& json, const char* kty) { if (!OSSL_PARAM_BLD_push_BN(bld, "n", tmp_n) || !OSSL_PARAM_BLD_push_BN(bld, "e", tmp_e) || (params = OSSL_PARAM_BLD_to_param(bld)) == NULL) { - gpr_log(GPR_ERROR, "Could not create OSSL_PARAM"); + LOG(ERROR) << "Could not create OSSL_PARAM"; goto end; } ctx = EVP_PKEY_CTX_new_from_name(nullptr, "RSA", nullptr); if (ctx == nullptr) { - gpr_log(GPR_ERROR, "Could not create rsa key."); + LOG(ERROR) << "Could not create rsa key."; goto end; } if (EVP_PKEY_fromdata_init(ctx) <= 0) { - gpr_log(GPR_ERROR, "Could not create rsa key."); + LOG(ERROR) << "Could not create rsa key."; goto end; } if (EVP_PKEY_fromdata(ctx, &result, EVP_PKEY_KEYPAIR, params) <= 0) { - gpr_log(GPR_ERROR, "Cannot set RSA key from inputs."); + LOG(ERROR) << "Cannot set RSA key from inputs."; goto end; } #endif @@ -618,8 +619,7 @@ static EVP_PKEY* find_verification_key(const Json& json, const char* header_alg, return extract_pkey_from_x509(cur->string().c_str()); } if (jwt_keys->type() != Json::Type::kArray) { - gpr_log(GPR_ERROR, - "Unexpected value type of keys property in jwks key set."); + LOG(ERROR) << "Unexpected value type of keys property in jwks key set."; return nullptr; } // Key format is specified in: @@ -661,21 +661,21 @@ static int verify_jwt_signature(EVP_PKEY* key, const char* alg, CHECK_NE(md, nullptr); // Checked before. if (md_ctx == nullptr) { - gpr_log(GPR_ERROR, "Could not create EVP_MD_CTX."); + LOG(ERROR) << "Could not create EVP_MD_CTX."; goto end; } if (EVP_DigestVerifyInit(md_ctx, nullptr, md, nullptr, key) != 1) { - gpr_log(GPR_ERROR, "EVP_DigestVerifyInit failed."); + LOG(ERROR) << "EVP_DigestVerifyInit failed."; goto end; } if (EVP_DigestVerifyUpdate(md_ctx, GRPC_SLICE_START_PTR(signed_data), GRPC_SLICE_LENGTH(signed_data)) != 1) { - gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); + LOG(ERROR) << "EVP_DigestVerifyUpdate failed."; goto end; } if (EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(signature), GRPC_SLICE_LENGTH(signature)) != 1) { - gpr_log(GPR_ERROR, "JWT signature verification failed."); + LOG(ERROR) << "JWT signature verification failed."; goto end; } @@ -742,7 +742,7 @@ static void on_openid_config_retrieved(void* user_data, if (json.type() == Json::Type::kNull) goto error; cur = find_property_by_name(json, "jwks_uri"); if (cur == nullptr) { - gpr_log(GPR_ERROR, "Could not find jwks_uri in openid config."); + LOG(ERROR) << "Could not find jwks_uri in openid config."; goto error; } jwks_uri = validate_string_field(*cur, "jwks_uri"); @@ -843,11 +843,11 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) { CHECK(ctx != nullptr && ctx->header != nullptr && ctx->claims != nullptr); iss = ctx->claims->iss; if (ctx->header->kid == nullptr) { - gpr_log(GPR_ERROR, "Missing kid in jose header."); + LOG(ERROR) << "Missing kid in jose header."; goto error; } if (iss == nullptr) { - gpr_log(GPR_ERROR, "Missing iss in claims."); + LOG(ERROR) << "Missing iss in claims."; goto error; } @@ -862,7 +862,7 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) { CHECK_NE(ctx->verifier, nullptr); mapping = verifier_get_mapping(ctx->verifier, email_domain); if (mapping == nullptr) { - gpr_log(GPR_ERROR, "Missing mapping for issuer email."); + LOG(ERROR) << "Missing mapping for issuer email."; goto error; } host = gpr_strdup(mapping->key_url_prefix); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 4c425b87470..6d2457dba2d 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -34,6 +34,7 @@ #include "absl/base/thread_annotations.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -1138,8 +1139,7 @@ void FilterStackCall::RecvTrailingFilter(grpc_metadata_batch* b, } else if (!is_client()) { SetFinalStatus(absl::OkStatus()); } else { - gpr_log(GPR_DEBUG, - "Received trailing metadata with no error and no status"); + VLOG(2) << "Received trailing metadata with no error and no status"; SetFinalStatus(grpc_error_set_int(GRPC_ERROR_CREATE("No status received"), StatusIntProperty::kRpcStatus, GRPC_STATUS_UNKNOWN)); diff --git a/src/core/load_balancing/xds/xds_override_host.cc b/src/core/load_balancing/xds/xds_override_host.cc index c8821ca0a91..41b3eb36ef6 100644 --- a/src/core/load_balancing/xds/xds_override_host.cc +++ b/src/core/load_balancing/xds/xds_override_host.cc @@ -32,6 +32,7 @@ #include "absl/base/thread_annotations.h" #include "absl/functional/function_ref.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" @@ -530,7 +531,7 @@ XdsOverrideHostLb::Picker::PickOverridenHost( // a connection attempt and queue the pick until that attempt completes. if (idle_subchannel != nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { - gpr_log(GPR_INFO, "Picker override found IDLE subchannel"); + LOG(INFO) << "Picker override found IDLE subchannel"; } // Deletes itself after the connection is requested. new SubchannelConnectionRequester(std::move(idle_subchannel)); @@ -540,7 +541,7 @@ XdsOverrideHostLb::Picker::PickOverridenHost( // queue the pick and wait for the connection attempt to complete. if (found_connecting) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { - gpr_log(GPR_INFO, "Picker override found CONNECTING subchannel"); + LOG(INFO) << "Picker override found CONNECTING subchannel"; } return PickResult::Queue(); } @@ -549,7 +550,7 @@ XdsOverrideHostLb::Picker::PickOverridenHost( // creation of a subchannel for that entry. if (!address_with_no_subchannel.empty()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { - gpr_log(GPR_INFO, "Picker override found entry with no subchannel"); + LOG(INFO) << "Picker override found entry with no subchannel"; } if (!IsWorkSerializerDispatchEnabled()) { new SubchannelCreationRequester(policy_, address_with_no_subchannel); diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 11849b655b8..fa22ca884b7 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -23,6 +23,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "upb/mem/arena.hpp" #include @@ -87,7 +88,7 @@ typedef struct alts_tsi_handshaker_result { static tsi_result handshaker_result_extract_peer( const tsi_handshaker_result* self, tsi_peer* peer) { if (self == nullptr || peer == nullptr) { - gpr_log(GPR_ERROR, "Invalid argument to handshaker_result_extract_peer()"); + LOG(ERROR) << "Invalid argument to handshaker_result_extract_peer()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -97,7 +98,7 @@ static tsi_result handshaker_result_extract_peer( tsi_result ok = tsi_construct_peer(kTsiAltsNumOfPeerProperties, peer); int index = 0; if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to construct tsi peer"); + LOG(ERROR) << "Failed to construct tsi peer"; return ok; } CHECK_NE(&peer->properties[index], nullptr); @@ -106,7 +107,7 @@ static tsi_result handshaker_result_extract_peer( &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; return ok; } index++; @@ -116,7 +117,7 @@ static tsi_result handshaker_result_extract_peer( &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } index++; CHECK_NE(&peer->properties[index], nullptr); @@ -126,7 +127,7 @@ static tsi_result handshaker_result_extract_peer( GRPC_SLICE_LENGTH(result->rpc_versions), &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } index++; CHECK_NE(&peer->properties[index], nullptr); @@ -136,7 +137,7 @@ static tsi_result handshaker_result_extract_peer( GRPC_SLICE_LENGTH(result->serialized_context), &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } index++; CHECK_NE(&peer->properties[index], nullptr); @@ -146,7 +147,7 @@ static tsi_result handshaker_result_extract_peer( &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } CHECK(++index == kTsiAltsNumOfPeerProperties); return ok; @@ -163,8 +164,7 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector( const tsi_handshaker_result* self, size_t* max_output_protected_frame_size, tsi_zero_copy_grpc_protector** protector) { if (self == nullptr || protector == nullptr) { - gpr_log(GPR_ERROR, - "Invalid arguments to create_zero_copy_grpc_protector()"); + LOG(ERROR) << "Invalid arguments to create_zero_copy_grpc_protector()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -198,7 +198,7 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector( /*is_integrity_only=*/false, /*enable_extra_copy=*/false, max_output_protected_frame_size, protector); if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector"); + LOG(ERROR) << "Failed to create zero-copy grpc protector"; } return ok; } @@ -207,8 +207,8 @@ static tsi_result handshaker_result_create_frame_protector( const tsi_handshaker_result* self, size_t* max_output_protected_frame_size, tsi_frame_protector** protector) { if (self == nullptr || protector == nullptr) { - gpr_log(GPR_ERROR, - "Invalid arguments to handshaker_result_create_frame_protector()"); + LOG(ERROR) + << "Invalid arguments to handshaker_result_create_frame_protector()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -219,7 +219,7 @@ static tsi_result handshaker_result_create_frame_protector( kAltsAes128GcmRekeyKeyLength, result->is_client, /*is_rekey=*/true, max_output_protected_frame_size, protector); if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to create frame protector"); + LOG(ERROR) << "Failed to create frame protector"; } return ok; } @@ -228,8 +228,7 @@ static tsi_result handshaker_result_get_unused_bytes( const tsi_handshaker_result* self, const unsigned char** bytes, size_t* bytes_size) { if (self == nullptr || bytes == nullptr || bytes_size == nullptr) { - gpr_log(GPR_ERROR, - "Invalid arguments to handshaker_result_get_unused_bytes()"); + LOG(ERROR) << "Invalid arguments to handshaker_result_get_unused_bytes()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -267,7 +266,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, bool is_client, tsi_handshaker_result** result) { if (result == nullptr || resp == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()"); + LOG(ERROR) << "Invalid arguments to create_handshaker_result()"; return TSI_INVALID_ARGUMENT; } const grpc_gcp_HandshakerResult* hresult = @@ -275,42 +274,42 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, const grpc_gcp_Identity* identity = grpc_gcp_HandshakerResult_peer_identity(hresult); if (identity == nullptr) { - gpr_log(GPR_ERROR, "Invalid identity"); + LOG(ERROR) << "Invalid identity"; return TSI_FAILED_PRECONDITION; } upb_StringView peer_service_account = grpc_gcp_Identity_service_account(identity); if (peer_service_account.size == 0) { - gpr_log(GPR_ERROR, "Invalid peer service account"); + LOG(ERROR) << "Invalid peer service account"; return TSI_FAILED_PRECONDITION; } upb_StringView key_data = grpc_gcp_HandshakerResult_key_data(hresult); if (key_data.size < kAltsAes128GcmRekeyKeyLength) { - gpr_log(GPR_ERROR, "Bad key length"); + LOG(ERROR) << "Bad key length"; return TSI_FAILED_PRECONDITION; } const grpc_gcp_RpcProtocolVersions* peer_rpc_version = grpc_gcp_HandshakerResult_peer_rpc_versions(hresult); if (peer_rpc_version == nullptr) { - gpr_log(GPR_ERROR, "Peer does not set RPC protocol versions."); + LOG(ERROR) << "Peer does not set RPC protocol versions."; return TSI_FAILED_PRECONDITION; } upb_StringView application_protocol = grpc_gcp_HandshakerResult_application_protocol(hresult); if (application_protocol.size == 0) { - gpr_log(GPR_ERROR, "Invalid application protocol"); + LOG(ERROR) << "Invalid application protocol"; return TSI_FAILED_PRECONDITION; } upb_StringView record_protocol = grpc_gcp_HandshakerResult_record_protocol(hresult); if (record_protocol.size == 0) { - gpr_log(GPR_ERROR, "Invalid record protocol"); + LOG(ERROR) << "Invalid record protocol"; return TSI_FAILED_PRECONDITION; } const grpc_gcp_Identity* local_identity = grpc_gcp_HandshakerResult_local_identity(hresult); if (local_identity == nullptr) { - gpr_log(GPR_ERROR, "Invalid local identity"); + LOG(ERROR) << "Invalid local identity"; return TSI_FAILED_PRECONDITION; } upb_StringView local_service_account = @@ -331,7 +330,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, bool serialized = grpc_gcp_rpc_protocol_versions_encode( peer_rpc_version, rpc_versions_arena.ptr(), &sresult->rpc_versions); if (!serialized) { - gpr_log(GPR_ERROR, "Failed to serialize peer's RPC protocol versions."); + LOG(ERROR) << "Failed to serialize peer's RPC protocol versions."; return TSI_FAILED_PRECONDITION; } upb::Arena context_arena; @@ -348,7 +347,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, context, const_cast(peer_rpc_version)); grpc_gcp_Identity* peer_identity = const_cast(identity); if (peer_identity == nullptr) { - gpr_log(GPR_ERROR, "Null peer identity in ALTS context."); + LOG(ERROR) << "Null peer identity in ALTS context."; return TSI_FAILED_PRECONDITION; } if (grpc_gcp_Identity_attributes_size(identity) != 0) { @@ -372,7 +371,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, char* serialized_ctx = grpc_gcp_AltsContext_serialize( context, context_arena.ptr(), &serialized_ctx_length); if (serialized_ctx == nullptr) { - gpr_log(GPR_ERROR, "Failed to serialize peer's ALTS context."); + LOG(ERROR) << "Failed to serialize peer's ALTS context."; return TSI_FAILED_PRECONDITION; } sresult->serialized_context = @@ -388,7 +387,7 @@ static void on_handshaker_service_resp_recv(void* arg, grpc_error_handle error) { alts_handshaker_client* client = static_cast(arg); if (client == nullptr) { - gpr_log(GPR_ERROR, "ALTS handshaker client is nullptr"); + LOG(ERROR) << "ALTS handshaker client is nullptr"; return; } bool success = true; @@ -440,7 +439,7 @@ static tsi_result alts_tsi_handshaker_continue_handshaker_next( handshaker->client_vtable_for_testing, handshaker->is_client, handshaker->max_frame_size, error); if (client == nullptr) { - gpr_log(GPR_ERROR, "Failed to create ALTS handshaker client"); + LOG(ERROR) << "Failed to create ALTS handshaker client"; if (error != nullptr) *error = "Failed to create ALTS handshaker client"; return TSI_FAILED_PRECONDITION; } @@ -449,7 +448,7 @@ static tsi_result alts_tsi_handshaker_continue_handshaker_next( CHECK_EQ(handshaker->client, nullptr); handshaker->client = client; if (handshaker->shutdown) { - gpr_log(GPR_INFO, "TSI handshake shutdown"); + LOG(INFO) << "TSI handshake shutdown"; if (error != nullptr) *error = "TSI handshaker shutdown"; return TSI_HANDSHAKE_SHUTDOWN; } @@ -529,7 +528,7 @@ static tsi_result handshaker_next( size_t* /*bytes_to_send_size*/, tsi_handshaker_result** /*result*/, tsi_handshaker_on_next_done_cb cb, void* user_data, std::string* error) { if (self == nullptr || cb == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()"); + LOG(ERROR) << "Invalid arguments to handshaker_next()"; if (error != nullptr) *error = "invalid argument"; return TSI_INVALID_ARGUMENT; } @@ -538,7 +537,7 @@ static tsi_result handshaker_next( { grpc_core::MutexLock lock(&handshaker->mu); if (handshaker->shutdown) { - gpr_log(GPR_INFO, "TSI handshake shutdown"); + LOG(INFO) << "TSI handshake shutdown"; if (error != nullptr) *error = "handshake shutdown"; return TSI_HANDSHAKE_SHUTDOWN; } @@ -569,7 +568,7 @@ static tsi_result handshaker_next( tsi_result ok = alts_tsi_handshaker_continue_handshaker_next( handshaker, received_bytes, received_bytes_size, cb, user_data, error); if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to schedule ALTS handshaker requests"); + LOG(ERROR) << "Failed to schedule ALTS handshaker requests"; return ok; } } @@ -651,7 +650,7 @@ tsi_result alts_tsi_handshaker_create( size_t user_specified_max_frame_size) { if (handshaker_service_url == nullptr || self == nullptr || options == nullptr || (is_client && target_name == nullptr)) { - gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_handshaker_create()"); + LOG(ERROR) << "Invalid arguments to alts_tsi_handshaker_create()"; return TSI_INVALID_ARGUMENT; } bool use_dedicated_cq = interested_parties == nullptr; From 1da5aaf8550bf0b1908dbee7bf5d4a1ebe8113e5 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Mon, 13 May 2024 03:18:46 -0700 Subject: [PATCH 28/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD (#36588) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD In this CL we are just editing the build and bzl files to add dependencies. This is done to prevent merge conflict and constantly having to re-make the make files using generate_projects.sh for each set of changes. Closes #36588 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36588 from tanvi-jagtap:build_src_cpp 1b7e617bdd93f2680ae7c41995d67113b5278a99 PiperOrigin-RevId: 633149794 --- src/cpp/ext/csm/BUILD | 1 + src/cpp/ext/gcp/BUILD | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/cpp/ext/csm/BUILD b/src/cpp/ext/csm/BUILD index fda0e37dbe8..6ee6bef1d4a 100644 --- a/src/cpp/ext/csm/BUILD +++ b/src/cpp/ext/csm/BUILD @@ -42,6 +42,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", diff --git a/src/cpp/ext/gcp/BUILD b/src/cpp/ext/gcp/BUILD index a95fe68b71c..814bf9012a2 100644 --- a/src/cpp/ext/gcp/BUILD +++ b/src/cpp/ext/gcp/BUILD @@ -115,6 +115,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/numeric:int128", "absl/strings", "absl/strings:str_format", @@ -157,6 +158,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", From 28b4fafc002cd9c454caa62193e339fdddc25f61 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Mon, 13 May 2024 03:28:10 -0700 Subject: [PATCH 29/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD (#36593) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD In this CL we are just editing the build and bzl files to add dependencies. This is done to prevent merge conflict and constantly having to re-make the make files using generate_projects.sh for each set of changes. Closes #36593 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36593 from tanvi-jagtap:build_src_core_ext_transport d73925c0f1a0b1c65cee851ca7497afdf35e7fbe PiperOrigin-RevId: 633151530 --- src/core/ext/transport/cronet/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ext/transport/cronet/BUILD b/src/core/ext/transport/cronet/BUILD index 50897682381..1e7e8253e62 100644 --- a/src/core/ext/transport/cronet/BUILD +++ b/src/core/ext/transport/cronet/BUILD @@ -41,6 +41,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "cronet_c_for_grpc", ], language = "c++", From 766226814a8746e1418051b3d876a49a448d607b Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Mon, 13 May 2024 03:34:24 -0700 Subject: [PATCH 30/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD (#36592) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD In this CL we are just editing the build and bzl files to add dependencies. This is done to prevent merge conflict and constantly having to re-make the make files using generate_projects.sh for each set of changes. Closes #36592 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36592 from tanvi-jagtap:build_src_core b36408ae0ebe291352db60a8e0b12fef95046587 PiperOrigin-RevId: 633152985 --- src/core/BUILD | 125 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/src/core/BUILD b/src/core/BUILD index b15bf14f933..babf6143381 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -216,6 +216,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -414,6 +415,7 @@ grpc_cc_library( "lib/gprpp/validation_errors.h", ], external_deps = [ + "absl/log:log", "absl/status", "absl/strings", ], @@ -530,7 +532,10 @@ grpc_cc_library( grpc_cc_library( name = "map_pipe", - external_deps = ["absl/status"], + external_deps = [ + "absl/log:log", + "absl/status", + ], language = "c++", public_hdrs = [ "lib/promise/map_pipe.h", @@ -559,6 +564,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", ], @@ -1003,6 +1009,7 @@ grpc_cc_library( name = "latch", external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -1021,6 +1028,7 @@ grpc_cc_library( name = "inter_activity_latch", external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/strings", ], language = "c++", @@ -1043,6 +1051,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", "absl/types:optional", @@ -1066,6 +1075,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/types:optional", "absl/types:variant", @@ -1177,6 +1187,7 @@ grpc_cc_library( name = "for_each", external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", ], @@ -1199,6 +1210,7 @@ grpc_cc_library( name = "ref_counted", external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", public_hdrs = ["lib/gprpp/ref_counted.h"], @@ -1215,6 +1227,7 @@ grpc_cc_library( name = "dual_ref_counted", external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", public_hdrs = ["lib/gprpp/dual_ref_counted.h"], @@ -1410,6 +1423,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:flat_hash_set", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -1460,6 +1474,9 @@ grpc_cc_library( hdrs = [ "lib/resource_quota/arena.h", ], + external_deps = [ + "absl/log:log", + ], visibility = [ "@grpc:alt_grpc_base_legacy", ], @@ -1559,6 +1576,9 @@ grpc_cc_library( hdrs = [ "lib/slice/slice_refcount.h", ], + external_deps = [ + "absl/log:log", + ], public_hdrs = [ "//:include/grpc/slice.h", ], @@ -1626,6 +1646,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -1653,6 +1674,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:str_format", ], visibility = ["@grpc:alt_grpc_base_legacy"], @@ -1674,6 +1696,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:str_format", "absl/types:optional", ], @@ -1755,6 +1778,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "//:config_vars", @@ -1904,6 +1928,7 @@ grpc_cc_library( "absl/container:flat_hash_set", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/time", "absl/types:optional", ], @@ -1954,6 +1979,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/time", "absl/types:optional", ], @@ -2111,6 +2137,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2217,6 +2244,7 @@ grpc_cc_library( ], external_deps = [ "absl/functional:any_invocable", + "absl/log:log", "absl/status", "absl/types:optional", ], @@ -2241,6 +2269,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2302,6 +2331,7 @@ grpc_cc_library( external_deps = [ "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2334,6 +2364,7 @@ grpc_cc_library( external_deps = [ "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2361,6 +2392,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2397,6 +2429,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2439,6 +2472,7 @@ grpc_cc_library( hdrs = ["lib/event_engine/windows/windows_engine.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2493,6 +2527,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -2522,6 +2557,7 @@ grpc_cc_library( "absl/cleanup", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -2550,6 +2586,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings:str_format", @@ -2584,6 +2621,7 @@ grpc_cc_library( external_deps = [ "absl/container:flat_hash_map", "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", ], @@ -2618,6 +2656,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2644,6 +2683,9 @@ grpc_cc_library( hdrs = [ "lib/event_engine/trace.h", ], + external_deps = [ + "absl/log:log", + ], deps = [ "//:gpr", "//:gpr_platform", @@ -2834,6 +2876,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2890,6 +2933,7 @@ grpc_cc_library( hdrs = ["lib/transport/bdp_estimator.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -3075,6 +3119,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/strings", "absl/types:optional", ], @@ -3151,7 +3196,10 @@ grpc_cc_library( hdrs = [ "service_config/service_config_parser.h", ], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", deps = [ "channel_args", @@ -3180,6 +3228,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/strings", "absl/strings:str_format", @@ -3355,6 +3404,7 @@ grpc_cc_library( "client_channel/retry_service_config.h", ], external_deps = [ + "absl/log:log", "absl/strings", "absl/types:optional", ], @@ -3405,6 +3455,7 @@ grpc_cc_library( "client_channel/backup_poller.h", ], external_deps = [ + "absl/log:log", "absl/status", ], language = "c++", @@ -3428,6 +3479,7 @@ grpc_cc_library( "service_config/service_config_channel_arg_filter.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", @@ -3514,6 +3566,7 @@ grpc_cc_library( hdrs = ["load_balancing/lb_policy_registry.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3624,6 +3677,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3763,6 +3817,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -3810,6 +3865,7 @@ grpc_cc_library( "lib/security/authorization/grpc_server_authz_filter.h", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3852,6 +3908,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/container:flat_hash_map", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3885,6 +3942,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3965,6 +4023,9 @@ grpc_cc_library( hdrs = [ "tsi/local_transport_security.h", ], + external_deps = [ + "absl/log:log", + ], language = "c++", deps = [ "//:event_engine_base_hdrs", @@ -3986,6 +4047,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4033,6 +4095,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/strings:str_format", @@ -4078,6 +4141,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -4160,6 +4224,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:bind_front", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4246,6 +4311,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4308,6 +4374,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4354,6 +4421,7 @@ grpc_cc_library( "lib/http/httpcli_ssl_credentials.h", ], external_deps = [ + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -4428,6 +4496,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4578,6 +4647,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -4659,6 +4729,7 @@ grpc_cc_library( "ext/filters/message_size/message_size_filter.h", ], external_deps = [ + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/strings:str_format", @@ -4707,6 +4778,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -5099,6 +5171,7 @@ grpc_cc_library( "absl/cleanup", "absl/functional:bind_front", "absl/log:check", + "absl/log:log", "absl/memory", "absl/random", "absl/status", @@ -5283,6 +5356,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5361,6 +5435,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5421,6 +5496,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5471,6 +5547,7 @@ grpc_cc_library( "load_balancing/xds/xds_cluster_manager.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5514,6 +5591,7 @@ grpc_cc_library( "load_balancing/xds/xds_wrr_locality.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5583,6 +5661,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5630,6 +5709,7 @@ grpc_cc_library( external_deps = [ "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", @@ -5754,7 +5834,10 @@ grpc_cc_library( hdrs = [ "lib/transport/connectivity_state.h", ], - external_deps = ["absl/status"], + external_deps = [ + "absl/log:log", + "absl/status", + ], deps = [ "closure", "error", @@ -5789,6 +5872,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5839,6 +5923,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -6013,6 +6098,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6061,6 +6147,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -6172,6 +6259,7 @@ grpc_cc_library( ], external_deps = [ "absl/container:inlined_vector", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6216,6 +6304,7 @@ grpc_cc_library( "ext/filters/backend_metrics/backend_metric_filter.h", ], external_deps = [ + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -6256,6 +6345,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6320,6 +6410,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6361,7 +6452,10 @@ grpc_cc_library( hdrs = [ "resolver/dns/dns_resolver_plugin.h", ], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", deps = [ "experiments", @@ -6385,6 +6479,7 @@ grpc_cc_library( ], external_deps = [ "absl/functional:bind_front", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6418,6 +6513,7 @@ grpc_cc_library( "resolver/sockaddr/sockaddr_resolver.cc", ], external_deps = [ + "absl/log:log", "absl/status:statusor", "absl/strings", ], @@ -6442,6 +6538,7 @@ grpc_cc_library( "resolver/binder/binder_resolver.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6503,6 +6600,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/container:flat_hash_set", "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -6526,6 +6624,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -6587,6 +6686,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -6654,6 +6754,7 @@ grpc_cc_library( external_deps = [ "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/strings:str_format", @@ -6848,6 +6949,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings:str_format", @@ -6905,6 +7007,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6966,6 +7069,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -7091,6 +7195,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -7144,6 +7249,7 @@ grpc_cc_library( "ext/filters/logging/logging_filter.h", ], external_deps = [ + "absl/log:log", "absl/numeric:int128", "absl/random", "absl/random:distributions", @@ -7222,7 +7328,10 @@ grpc_cc_library( hdrs = [ "ext/transport/chaotic_good/chaotic_good_transport.h", ], - external_deps = ["absl/random"], + external_deps = [ + "absl/log:log", + "absl/random", + ], language = "c++", deps = [ "chaotic_good_frame", @@ -7251,6 +7360,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:flat_hash_map", "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -7309,6 +7419,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -7394,6 +7505,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "call_final_info", @@ -7504,6 +7616,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "1999", @@ -7641,6 +7754,7 @@ grpc_cc_library( external_deps = [ "absl/container:flat_hash_map", "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -7706,6 +7820,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", From 88ed4299f9911b4391d91c19bf76ef02055a7b24 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Mon, 13 May 2024 07:22:27 -0700 Subject: [PATCH 31/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD (#36587) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD In this CL we are just editing the build and bzl files to add dependencies. This is done to prevent merge conflict and constantly having to re-make the make files using generate_projects.sh for each set of changes. Closes #36587 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36587 from tanvi-jagtap:build_include 2a167f6e52b7e900d019f92993d503d5b4622a50 PiperOrigin-RevId: 633201049 --- BUILD | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BUILD b/BUILD index 7a295c7991b..00b47379fb3 100644 --- a/BUILD +++ b/BUILD @@ -906,6 +906,7 @@ grpc_cc_library( hdrs = GRPCXX_PUBLIC_HDRS, external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:cord", "absl/synchronization", "protobuf_headers", @@ -936,6 +937,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:cord", ], language = "c++", @@ -1250,6 +1252,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/synchronization", ], @@ -2457,6 +2460,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2541,6 +2545,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", From c31b115a6307be6046624df3208bd4afb676c409 Mon Sep 17 00:00:00 2001 From: Tanvi Jagtap <139093547+tanvi-jagtap@users.noreply.github.com> Date: Mon, 13 May 2024 07:55:29 -0700 Subject: [PATCH 32/33] [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD (#36591) [grpc][Gpr_To_Absl_Logging] Migrating from gpr to absl logging - BUILD In this CL we are just editing the build and bzl files to add dependencies. This is done to prevent merge conflict and constantly having to re-make the make files using generate_projects.sh for each set of changes. Closes #36591 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36591 from tanvi-jagtap:build_root_02 62ee245c88b610d6aca9de5215a97548602da682 PiperOrigin-RevId: 633209659 --- BUILD | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/BUILD b/BUILD index 00b47379fb3..0c113b8bf25 100644 --- a/BUILD +++ b/BUILD @@ -583,6 +583,7 @@ grpc_cc_library( defines = ["GRPC_NO_XDS"], external_deps = [ "absl/base:core_headers", + "absl/log:log", ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, @@ -654,6 +655,7 @@ grpc_cc_library( }), external_deps = [ "absl/base:core_headers", + "absl/log:log", ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, @@ -787,9 +789,9 @@ grpc_cc_library( "absl/base:core_headers", "absl/base:log_severity", "absl/functional:any_invocable", - "absl/log", "absl/log:check", "absl/log:globals", + "absl/log:log", "absl/memory", "absl/random", "absl/status", @@ -1007,6 +1009,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -1066,6 +1069,7 @@ grpc_cc_library( ], external_deps = [ "absl/container:flat_hash_set", + "absl/log:log", "absl/strings", "absl/types:optional", "absl/types:span", @@ -1385,6 +1389,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -1444,6 +1449,7 @@ grpc_cc_library( external_deps = [ "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", ], language = "c++", deps = [ @@ -1495,6 +1501,9 @@ grpc_cc_library( hdrs = [ "//src/core:lib/surface/api_trace.h", ], + external_deps = [ + "absl/log:log", + ], language = "c++", deps = [ "gpr", @@ -1813,6 +1822,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", @@ -1902,6 +1912,7 @@ grpc_cc_library( "absl/container:flat_hash_set", "absl/hash", "absl/log:check", + "absl/log:log", "absl/random", "absl/status", "absl/status:statusor", @@ -2295,6 +2306,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2402,6 +2414,7 @@ grpc_cc_library( "//src/core:tsi/alts/handshaker/transport_security_common_api.h", ], external_deps = [ + "absl/log:log", "@com_google_protobuf//upb:base", "@com_google_protobuf//upb:mem", ], @@ -2979,6 +2992,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", ], language = "c++", visibility = ["@grpc:client_channel"], @@ -2999,7 +3013,10 @@ grpc_cc_library( name = "grpc_trace", srcs = ["//src/core:lib/debug/trace.cc"], hdrs = ["//src/core:lib/debug/trace.h"], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", visibility = ["@grpc:trace"], deps = [ @@ -3144,6 +3161,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -3180,6 +3198,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -3226,6 +3245,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:str_format", ], visibility = [ @@ -3257,6 +3277,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3291,6 +3312,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", ], @@ -3319,6 +3341,9 @@ grpc_cc_library( hdrs = [ "//src/core:lib/iomgr/internal_errqueue.h", ], + external_deps = [ + "absl/log:log", + ], tags = ["nofixdeps"], visibility = ["@grpc:iomgr_internal_errqueue"], deps = [ @@ -3337,6 +3362,7 @@ grpc_cc_library( "//src/core:lib/iomgr/buffer_list.h", ], external_deps = [ + "absl/log:log", "absl/strings", "absl/strings:str_format", "absl/types:optional", @@ -3383,6 +3409,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3550,6 +3577,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3583,6 +3611,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "@com_google_protobuf//upb:base", @@ -3625,6 +3654,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", ], @@ -3816,6 +3846,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3880,6 +3911,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:bind_front", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3934,6 +3966,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -3978,6 +4011,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", visibility = [ @@ -4066,7 +4100,10 @@ grpc_cc_library( "//src/core:lib/security/security_connector/load_system_roots_supported.h", "//src/core:lib/security/util/json_util.h", ], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", visibility = ["@grpc:public"], deps = [ @@ -4159,6 +4196,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/types:span", "libcrypto", "libssl", @@ -4190,6 +4228,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/memory", "libssl", ], @@ -4270,6 +4309,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4522,6 +4562,7 @@ grpc_cc_library( external_deps = [ "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", ], @@ -4578,6 +4619,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/random:bit_gen_ref", "absl/status", "absl/strings", @@ -4620,6 +4662,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -4860,6 +4903,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/types:span", ], From 0ecee5ad3fe69fd4a6a8e82761e7c65113518b8f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 13 May 2024 09:42:24 -0700 Subject: [PATCH 33/33] [call-v3] Server path (#36509) Closes #36509 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36509 from ctiller:transport-refs-3 2771a2b0e1b4af4c5622839a5a767388d13b1074 PiperOrigin-RevId: 633240374 --- BUILD | 4 +- CMakeLists.txt | 3 + Makefile | 1 + Package.swift | 3 + bazel/experiments.bzl | 21 +- build_autogenerated.yaml | 9 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 4 + gRPC-Core.podspec | 5 + grpc.gemspec | 3 + package.xml | 3 + src/core/BUILD | 8 +- .../ext/filters/logging/logging_filter.cc | 4 +- .../chaotic_good/server_transport.cc | 76 +- .../transport/chaotic_good/server_transport.h | 12 +- .../ext/transport/inproc/inproc_transport.cc | 51 +- .../ext/transport/inproc/inproc_transport.h | 2 +- src/core/lib/channel/channel_stack.cc | 26 - src/core/lib/channel/channel_stack.h | 1 - src/core/lib/experiments/experiments.cc | 48 +- src/core/lib/experiments/experiments.h | 8 - src/core/lib/experiments/experiments.yaml | 11 +- src/core/lib/experiments/rollouts.yaml | 2 - src/core/lib/promise/detail/promise_like.h | 11 +- src/core/lib/promise/status_flag.h | 2 + src/core/lib/surface/call.cc | 1015 +++++------------ src/core/lib/surface/call.h | 60 +- src/core/lib/surface/channel_init.cc | 84 +- src/core/lib/surface/channel_init.h | 116 +- src/core/lib/surface/init.cc | 4 +- src/core/lib/transport/call_destination.h | 18 + src/core/lib/transport/call_filters.h | 44 + src/core/lib/transport/call_spine.h | 8 +- src/core/lib/transport/interception_chain.h | 11 + src/core/lib/transport/transport.h | 67 +- .../plugin_registry/grpc_plugin_registry.cc | 3 +- src/core/server/server.cc | 632 +++++----- src/core/server/server.h | 33 +- src/core/server/server_interface.h | 2 + src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/end2end/tests/filter_context.cc | 3 - test/core/surface/channel_init_test.cc | 33 +- .../chaotic_good/chaotic_good_server_test.cc | 6 +- .../chaotic_good/server_transport_test.cc | 37 +- .../core/transport/test_suite/call_content.cc | 2 +- test/core/transport/test_suite/call_shapes.cc | 18 +- .../transport/test_suite/inproc_fixture.cc | 6 +- test/core/transport/test_suite/no_op.cc | 4 +- test/core/transport/test_suite/stress.cc | 2 +- test/core/transport/test_suite/test.cc | 29 +- test/core/transport/test_suite/test.h | 17 +- ..._fullstack_unary_ping_pong_chaotic_good.cc | 1 - tools/doxygen/Doxyfile.c++.internal | 3 + tools/doxygen/Doxyfile.core.internal | 3 + 55 files changed, 991 insertions(+), 1591 deletions(-) diff --git a/BUILD b/BUILD index 0c113b8bf25..f83a6bdc989 100644 --- a/BUILD +++ b/BUILD @@ -1942,9 +1942,7 @@ grpc_cc_library( "promise", "ref_counted_ptr", "stats", - "//src/core:1999", "//src/core:activity", - "//src/core:arena", "//src/core:arena_promise", "//src/core:cancel_callback", "//src/core:channel_args", @@ -1958,6 +1956,7 @@ grpc_cc_library( "//src/core:error", "//src/core:error_utils", "//src/core:experiments", + "//src/core:interception_chain", "//src/core:iomgr_fwd", "//src/core:map", "//src/core:metadata_batch", @@ -2078,6 +2077,7 @@ grpc_cc_library( "//src/core:arena_promise", "//src/core:atomic_utils", "//src/core:bitset", + "//src/core:call_destination", "//src/core:call_filters", "//src/core:call_final_info", "//src/core:call_finalization", diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b107dddb0f..3499823786a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2502,6 +2502,7 @@ add_library(grpc src/core/lib/transport/call_spine.cc src/core/lib/transport/connectivity_state.cc src/core/lib/transport/error_utils.cc + src/core/lib/transport/interception_chain.cc src/core/lib/transport/message.cc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc @@ -3255,6 +3256,7 @@ add_library(grpc_unsecure src/core/lib/transport/call_spine.cc src/core/lib/transport/connectivity_state.cc src/core/lib/transport/error_utils.cc + src/core/lib/transport/interception_chain.cc src/core/lib/transport/message.cc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc @@ -5366,6 +5368,7 @@ add_library(grpc_authorization_provider src/core/lib/transport/call_spine.cc src/core/lib/transport/connectivity_state.cc src/core/lib/transport/error_utils.cc + src/core/lib/transport/interception_chain.cc src/core/lib/transport/message.cc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc diff --git a/Makefile b/Makefile index 25ebda3f986..22625964566 100644 --- a/Makefile +++ b/Makefile @@ -1387,6 +1387,7 @@ LIBGRPC_SRC = \ src/core/lib/transport/call_spine.cc \ src/core/lib/transport/connectivity_state.cc \ src/core/lib/transport/error_utils.cc \ + src/core/lib/transport/interception_chain.cc \ src/core/lib/transport/message.cc \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ diff --git a/Package.swift b/Package.swift index 81f99552ac2..c4405cf775f 100644 --- a/Package.swift +++ b/Package.swift @@ -1749,6 +1749,7 @@ let package = Package( "src/core/lib/transport/bdp_estimator.h", "src/core/lib/transport/call_arena_allocator.cc", "src/core/lib/transport/call_arena_allocator.h", + "src/core/lib/transport/call_destination.h", "src/core/lib/transport/call_filters.cc", "src/core/lib/transport/call_filters.h", "src/core/lib/transport/call_final_info.cc", @@ -1761,6 +1762,8 @@ let package = Package( "src/core/lib/transport/error_utils.cc", "src/core/lib/transport/error_utils.h", "src/core/lib/transport/http2_errors.h", + "src/core/lib/transport/interception_chain.cc", + "src/core/lib/transport/interception_chain.h", "src/core/lib/transport/message.cc", "src/core/lib/transport/message.h", "src/core/lib/transport/metadata.cc", diff --git a/bazel/experiments.bzl b/bazel/experiments.bzl index 096b07c8828..0bd711b6641 100644 --- a/bazel/experiments.bzl +++ b/bazel/experiments.bzl @@ -34,9 +34,8 @@ EXPERIMENT_ENABLES = { "pending_queue_cap": "pending_queue_cap", "pick_first_new": "pick_first_new", "promise_based_client_call": "event_engine_client,event_engine_listener,promise_based_client_call", - "promise_based_server_call": "promise_based_server_call", - "chaotic_good": "chaotic_good,event_engine_client,event_engine_listener,promise_based_client_call,promise_based_server_call", - "promise_based_inproc_transport": "event_engine_client,event_engine_listener,promise_based_client_call,promise_based_inproc_transport,promise_based_server_call", + "chaotic_good": "chaotic_good,event_engine_client,event_engine_listener,promise_based_client_call", + "promise_based_inproc_transport": "event_engine_client,event_engine_listener,promise_based_client_call,promise_based_inproc_transport", "rstpit": "rstpit", "schedule_cancellation_over_write": "schedule_cancellation_over_write", "server_privacy": "server_privacy", @@ -59,9 +58,6 @@ EXPERIMENTS = { "dbg": { }, "off": { - "core_end2end_test": [ - "promise_based_server_call", - ], "endpoint_test": [ "tcp_frame_size_tuning", "tcp_rcv_lowat", @@ -73,9 +69,6 @@ EXPERIMENTS = { "tcp_frame_size_tuning", "tcp_rcv_lowat", ], - "logging_test": [ - "promise_based_server_call", - ], "resource_quota_test": [ "free_large_allocator", "unconstrained_max_quota_buffer_size", @@ -107,9 +100,6 @@ EXPERIMENTS = { "dbg": { }, "off": { - "core_end2end_test": [ - "promise_based_server_call", - ], "endpoint_test": [ "tcp_frame_size_tuning", "tcp_rcv_lowat", @@ -121,9 +111,6 @@ EXPERIMENTS = { "tcp_frame_size_tuning", "tcp_rcv_lowat", ], - "logging_test": [ - "promise_based_server_call", - ], "resource_quota_test": [ "free_large_allocator", "unconstrained_max_quota_buffer_size", @@ -149,7 +136,6 @@ EXPERIMENTS = { "chaotic_good", "event_engine_client", "promise_based_client_call", - "promise_based_server_call", ], "endpoint_test": [ "tcp_frame_size_tuning", @@ -168,9 +154,6 @@ EXPERIMENTS = { "lame_client_test": [ "promise_based_client_call", ], - "logging_test": [ - "promise_based_server_call", - ], "resource_quota_test": [ "free_large_allocator", "unconstrained_max_quota_buffer_size", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 7458cc04b7f..b60ae5b5e2a 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -1110,6 +1110,7 @@ libs: - src/core/lib/transport/batch_builder.h - src/core/lib/transport/bdp_estimator.h - src/core/lib/transport/call_arena_allocator.h + - src/core/lib/transport/call_destination.h - src/core/lib/transport/call_filters.h - src/core/lib/transport/call_final_info.h - src/core/lib/transport/call_spine.h @@ -1117,6 +1118,7 @@ libs: - src/core/lib/transport/custom_metadata.h - src/core/lib/transport/error_utils.h - src/core/lib/transport/http2_errors.h + - src/core/lib/transport/interception_chain.h - src/core/lib/transport/message.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h @@ -1921,6 +1923,7 @@ libs: - src/core/lib/transport/call_spine.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc + - src/core/lib/transport/interception_chain.cc - src/core/lib/transport/message.cc - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc @@ -2609,6 +2612,7 @@ libs: - src/core/lib/transport/batch_builder.h - src/core/lib/transport/bdp_estimator.h - src/core/lib/transport/call_arena_allocator.h + - src/core/lib/transport/call_destination.h - src/core/lib/transport/call_filters.h - src/core/lib/transport/call_final_info.h - src/core/lib/transport/call_spine.h @@ -2616,6 +2620,7 @@ libs: - src/core/lib/transport/custom_metadata.h - src/core/lib/transport/error_utils.h - src/core/lib/transport/http2_errors.h + - src/core/lib/transport/interception_chain.h - src/core/lib/transport/message.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h @@ -3032,6 +3037,7 @@ libs: - src/core/lib/transport/call_spine.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc + - src/core/lib/transport/interception_chain.cc - src/core/lib/transport/message.cc - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc @@ -4686,6 +4692,7 @@ libs: - src/core/lib/surface/wait_for_cq_end_op.h - src/core/lib/transport/batch_builder.h - src/core/lib/transport/call_arena_allocator.h + - src/core/lib/transport/call_destination.h - src/core/lib/transport/call_filters.h - src/core/lib/transport/call_final_info.h - src/core/lib/transport/call_spine.h @@ -4693,6 +4700,7 @@ libs: - src/core/lib/transport/custom_metadata.h - src/core/lib/transport/error_utils.h - src/core/lib/transport/http2_errors.h + - src/core/lib/transport/interception_chain.h - src/core/lib/transport/message.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h @@ -4989,6 +4997,7 @@ libs: - src/core/lib/transport/call_spine.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc + - src/core/lib/transport/interception_chain.cc - src/core/lib/transport/message.cc - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc diff --git a/config.m4 b/config.m4 index d44618c5775..4b72ff9577e 100644 --- a/config.m4 +++ b/config.m4 @@ -762,6 +762,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/call_spine.cc \ src/core/lib/transport/connectivity_state.cc \ src/core/lib/transport/error_utils.cc \ + src/core/lib/transport/interception_chain.cc \ src/core/lib/transport/message.cc \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ diff --git a/config.w32 b/config.w32 index 0d0a85c04d7..f71331b6d7d 100644 --- a/config.w32 +++ b/config.w32 @@ -727,6 +727,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\transport\\call_spine.cc " + "src\\core\\lib\\transport\\connectivity_state.cc " + "src\\core\\lib\\transport\\error_utils.cc " + + "src\\core\\lib\\transport\\interception_chain.cc " + "src\\core\\lib\\transport\\message.cc " + "src\\core\\lib\\transport\\metadata.cc " + "src\\core\\lib\\transport\\metadata_batch.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ec37a7d2469..530f61b07aa 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -1213,6 +1213,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/batch_builder.h', 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.h', 'src/core/lib/transport/call_spine.h', @@ -1220,6 +1221,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/custom_metadata.h', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', @@ -2482,6 +2484,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/batch_builder.h', 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.h', 'src/core/lib/transport/call_spine.h', @@ -2489,6 +2492,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/custom_metadata.h', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5459da7206f..baff363da6c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1864,6 +1864,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.cc', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.cc', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.cc', @@ -1876,6 +1877,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/error_utils.cc', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.cc', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.cc', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.cc', @@ -3261,6 +3264,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/batch_builder.h', 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.h', 'src/core/lib/transport/call_spine.h', @@ -3268,6 +3272,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/custom_metadata.h', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', diff --git a/grpc.gemspec b/grpc.gemspec index 44f58db3185..4a58496ff43 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1751,6 +1751,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/bdp_estimator.h ) s.files += %w( src/core/lib/transport/call_arena_allocator.cc ) s.files += %w( src/core/lib/transport/call_arena_allocator.h ) + s.files += %w( src/core/lib/transport/call_destination.h ) s.files += %w( src/core/lib/transport/call_filters.cc ) s.files += %w( src/core/lib/transport/call_filters.h ) s.files += %w( src/core/lib/transport/call_final_info.cc ) @@ -1763,6 +1764,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/error_utils.cc ) s.files += %w( src/core/lib/transport/error_utils.h ) s.files += %w( src/core/lib/transport/http2_errors.h ) + s.files += %w( src/core/lib/transport/interception_chain.cc ) + s.files += %w( src/core/lib/transport/interception_chain.h ) s.files += %w( src/core/lib/transport/message.cc ) s.files += %w( src/core/lib/transport/message.h ) s.files += %w( src/core/lib/transport/metadata.cc ) diff --git a/package.xml b/package.xml index 70f64915ef8..44f87605fa6 100644 --- a/package.xml +++ b/package.xml @@ -1733,6 +1733,7 @@ + @@ -1745,6 +1746,8 @@ + + diff --git a/src/core/BUILD b/src/core/BUILD index babf6143381..a9580c2aaa6 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -664,7 +664,10 @@ grpc_cc_library( grpc_cc_library( name = "promise_like", - external_deps = ["absl/meta:type_traits"], + external_deps = [ + "absl/functional:any_invocable", + "absl/meta:type_traits", + ], language = "c++", public_hdrs = [ "lib/promise/detail/promise_like.h", @@ -3130,6 +3133,7 @@ grpc_cc_library( "channel_fwd", "channel_stack_trace", "channel_stack_type", + "interception_chain", "//:channel_stack_builder", "//:debug_location", "//:gpr", @@ -3147,6 +3151,7 @@ grpc_cc_library( deps = [ "channel_args", "//:channelz", + "//:event_engine_base_hdrs", "//:gpr_platform", ], ) @@ -7087,6 +7092,7 @@ grpc_cc_library( "experiments", "iomgr_fwd", "metadata_batch", + "resource_quota", "slice", "slice_buffer", "status_helper", diff --git a/src/core/ext/filters/logging/logging_filter.cc b/src/core/ext/filters/logging/logging_filter.cc index 1c76e64b06a..587e87ff506 100644 --- a/src/core/ext/filters/logging/logging_filter.cc +++ b/src/core/ext/filters/logging/logging_filter.cc @@ -539,11 +539,11 @@ void RegisterLoggingFilter(LoggingSink* sink) { g_logging_sink = sink; CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) { builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL) + ->RegisterV2Filter(GRPC_SERVER_CHANNEL) // TODO(yashykt) : Figure out a good place to place this channel arg .IfChannelArg("grpc.experimental.enable_observability", true); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_CHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_CHANNEL) // TODO(yashykt) : Figure out a good place to place this channel arg .IfChannelArg("grpc.experimental.enable_observability", true); }); diff --git a/src/core/ext/transport/chaotic_good/server_transport.cc b/src/core/ext/transport/chaotic_good/server_transport.cc index c139c6e44e0..98fbf4e915e 100644 --- a/src/core/ext/transport/chaotic_good/server_transport.cc +++ b/src/core/ext/transport/chaotic_good/server_transport.cc @@ -235,37 +235,27 @@ auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToNewCall( FrameHeader frame_header, BufferPair buffers, ChaoticGoodTransport& transport) { ClientFragmentFrame fragment_frame; - ScopedArenaPtr arena(acceptor_->CreateArena()); + ScopedArenaPtr arena(call_arena_allocator_->MakeArena()); absl::Status status = transport.DeserializeFrame( frame_header, std::move(buffers), arena.get(), fragment_frame, FrameLimits{1024 * 1024 * 1024, aligned_bytes_ - 1}); absl::optional call_initiator; if (status.ok()) { - auto create_call_result = acceptor_->CreateCall( - std::move(fragment_frame.headers), arena.release()); - if (grpc_chaotic_good_trace.enabled()) { - gpr_log(GPR_INFO, - "CHAOTIC_GOOD: DeserializeAndPushFragmentToNewCall: " - "create_call_result=%s", - create_call_result.ok() - ? "ok" - : create_call_result.status().ToString().c_str()); - } - if (create_call_result.ok()) { - call_initiator.emplace(std::move(*create_call_result)); - auto add_result = NewStream(frame_header.stream_id, *call_initiator); - if (add_result.ok()) { - call_initiator->SpawnGuarded( - "server-write", [this, stream_id = frame_header.stream_id, - call_initiator = *call_initiator]() { - return CallOutboundLoop(stream_id, call_initiator); - }); - } else { - call_initiator.reset(); - status = add_result; - } + auto call = + MakeCallPair(std::move(fragment_frame.headers), event_engine_.get(), + arena.release(), call_arena_allocator_, nullptr); + call_initiator.emplace(std::move(call.initiator)); + auto add_result = NewStream(frame_header.stream_id, *call_initiator); + if (add_result.ok()) { + call_destination_->StartCall(std::move(call.handler)); + call_initiator->SpawnGuarded( + "server-write", [this, stream_id = frame_header.stream_id, + call_initiator = *call_initiator]() { + return CallOutboundLoop(stream_id, call_initiator); + }); } else { - status = create_call_result.status(); + call_initiator.reset(); + status = add_result; } } return MaybePushFragmentIntoCall(std::move(call_initiator), std::move(status), @@ -366,10 +356,13 @@ ChaoticGoodServerTransport::ChaoticGoodServerTransport( PromiseEndpoint data_endpoint, std::shared_ptr event_engine, HPackParser hpack_parser, HPackCompressor hpack_encoder) - : outgoing_frames_(4), - allocator_(args.GetObject() - ->memory_quota() - ->CreateMemoryAllocator("chaotic-good")) { + : call_arena_allocator_(MakeRefCounted( + args.GetObject() + ->memory_quota() + ->CreateMemoryAllocator("chaotic-good"), + 1024)), + event_engine_(event_engine), + outgoing_frames_(4) { auto transport = MakeRefCounted( std::move(control_endpoint), std::move(data_endpoint), std::move(hpack_parser), std::move(hpack_encoder)); @@ -381,20 +374,25 @@ ChaoticGoodServerTransport::ChaoticGoodServerTransport( OnTransportActivityDone("reader")); } -void ChaoticGoodServerTransport::SetAcceptor(Acceptor* acceptor) { - CHECK_EQ(acceptor_, nullptr); - CHECK_NE(acceptor, nullptr); - acceptor_ = acceptor; +void ChaoticGoodServerTransport::SetCallDestination( + RefCountedPtr call_destination) { + CHECK(call_destination_ == nullptr); + CHECK(call_destination != nullptr); + call_destination_ = call_destination; got_acceptor_.Set(); } -ChaoticGoodServerTransport::~ChaoticGoodServerTransport() { - if (writer_ != nullptr) { - writer_.reset(); - } - if (reader_ != nullptr) { - reader_.reset(); +void ChaoticGoodServerTransport::Orphan() { + ActivityPtr writer; + ActivityPtr reader; + { + MutexLock lock(&mu_); + writer = std::move(writer_); + reader = std::move(reader_); } + writer.reset(); + reader.reset(); + Unref(); } void ChaoticGoodServerTransport::AbortWithError() { diff --git a/src/core/ext/transport/chaotic_good/server_transport.h b/src/core/ext/transport/chaotic_good/server_transport.h index a34ac92b73e..140641abcf6 100644 --- a/src/core/ext/transport/chaotic_good/server_transport.h +++ b/src/core/ext/transport/chaotic_good/server_transport.h @@ -86,7 +86,6 @@ class ChaoticGoodServerTransport final : public ServerTransport { std::shared_ptr event_engine, HPackParser hpack_parser, HPackCompressor hpack_encoder); - ~ChaoticGoodServerTransport() override; FilterStackTransport* filter_stack_transport() override { return nullptr; } ClientTransport* client_transport() override { return nullptr; } @@ -96,9 +95,10 @@ class ChaoticGoodServerTransport final : public ServerTransport { void SetPollsetSet(grpc_stream*, grpc_pollset_set*) override {} void PerformOp(grpc_transport_op*) override; grpc_endpoint* GetEndpoint() override { return nullptr; } - void Orphan() override { Unref(); } + void Orphan() override; - void SetAcceptor(Acceptor* acceptor) override; + void SetCallDestination( + RefCountedPtr call_destination) override; void AbortWithError(); private: @@ -137,7 +137,10 @@ class ChaoticGoodServerTransport final : public ServerTransport { auto PushFragmentIntoCall(CallInitiator call_initiator, ClientFragmentFrame frame, uint32_t stream_id); - Acceptor* acceptor_ = nullptr; + RefCountedPtr call_destination_; + const RefCountedPtr call_arena_allocator_; + const std::shared_ptr + event_engine_; InterActivityLatch got_acceptor_; MpscReceiver outgoing_frames_; // Assigned aligned bytes from setting frame. @@ -146,7 +149,6 @@ class ChaoticGoodServerTransport final : public ServerTransport { // Map of stream incoming server frames, key is stream_id. StreamMap stream_map_ ABSL_GUARDED_BY(mu_); uint32_t last_seen_new_stream_id_ = 0; - grpc_event_engine::experimental::MemoryAllocator allocator_; ActivityPtr writer_ ABSL_GUARDED_BY(mu_); ActivityPtr reader_ ABSL_GUARDED_BY(mu_); ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(mu_){ diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 7dd316bfca8..dbbd3e63123 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -28,6 +28,7 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/promise/promise.h" #include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/surface/channel_create.h" #include "src/core/lib/transport/transport.h" #include "src/core/server/server.h" @@ -39,8 +40,18 @@ class InprocClientTransport; class InprocServerTransport final : public ServerTransport { public: - void SetAcceptor(Acceptor* acceptor) override { - acceptor_ = acceptor; + explicit InprocServerTransport(const ChannelArgs& args) + : event_engine_( + args.GetObjectRef()), + call_arena_allocator_(MakeRefCounted( + args.GetObject() + ->memory_quota() + ->CreateMemoryAllocator("inproc_server"), + 1024)) {} + + void SetCallDestination( + RefCountedPtr unstarted_call_handler) override { + unstarted_call_handler_ = unstarted_call_handler; ConnectionState expect = ConnectionState::kInitial; state_.compare_exchange_strong(expect, ConnectionState::kReady, std::memory_order_acq_rel, @@ -95,7 +106,11 @@ class InprocServerTransport final : public ServerTransport { case ConnectionState::kReady: break; } - return acceptor_->CreateCall(std::move(md), acceptor_->CreateArena()); + auto* arena = call_arena_allocator_->MakeArena(); + auto server_call = MakeCallPair(std::move(md), event_engine_.get(), arena, + call_arena_allocator_, nullptr); + unstarted_call_handler_->StartCall(std::move(server_call.handler)); + return std::move(server_call.initiator); } OrphanablePtr MakeClientTransport(); @@ -105,11 +120,14 @@ class InprocServerTransport final : public ServerTransport { std::atomic state_{ConnectionState::kInitial}; std::atomic disconnecting_{false}; - Acceptor* acceptor_; + RefCountedPtr unstarted_call_handler_; absl::Status disconnect_error_; Mutex state_tracker_mu_; ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(state_tracker_mu_){ "inproc_server_transport", GRPC_CHANNEL_CONNECTING}; + const std::shared_ptr + event_engine_; + const RefCountedPtr call_arena_allocator_; }; class InprocClientTransport final : public ClientTransport { @@ -118,16 +136,19 @@ class InprocClientTransport final : public ClientTransport { RefCountedPtr server_transport) : server_transport_(std::move(server_transport)) {} - void StartCall(CallHandler call_handler) override { - call_handler.SpawnGuarded( + void StartCall(CallHandler child_call_handler) override { + child_call_handler.SpawnGuarded( "pull_initial_metadata", - TrySeq(call_handler.PullClientInitialMetadata(), + TrySeq(child_call_handler.PullClientInitialMetadata(), [server_transport = server_transport_, - call_handler](ClientMetadataHandle md) { - auto call_initiator = + child_call_handler](ClientMetadataHandle md) { + auto server_call_initiator = server_transport->AcceptCall(std::move(md)); - if (!call_initiator.ok()) return call_initiator.status(); - ForwardCall(call_handler, std::move(*call_initiator)); + if (!server_call_initiator.ok()) { + return server_call_initiator.status(); + } + ForwardCall(child_call_handler, + std::move(*server_call_initiator)); return absl::OkStatus(); })); } @@ -155,7 +176,6 @@ class InprocClientTransport final : public ClientTransport { bool UsePromiseBasedTransport() { if (!IsPromiseBasedInprocTransportEnabled()) return false; CHECK(IsPromiseBasedClientCallEnabled()); - CHECK(IsPromiseBasedServerCallEnabled()); return true; } @@ -180,7 +200,7 @@ OrphanablePtr MakeLameChannel(absl::string_view why, OrphanablePtr MakeInprocChannel(Server* server, ChannelArgs client_channel_args) { - auto transports = MakeInProcessTransportPair(); + auto transports = MakeInProcessTransportPair(server->channel_args()); auto client_transport = std::move(transports.first); auto server_transport = std::move(transports.second); auto error = @@ -205,8 +225,9 @@ OrphanablePtr MakeInprocChannel(Server* server, } // namespace std::pair, OrphanablePtr> -MakeInProcessTransportPair() { - auto server_transport = MakeOrphanable(); +MakeInProcessTransportPair(const ChannelArgs& server_channel_args) { + auto server_transport = + MakeOrphanable(server_channel_args); auto client_transport = server_transport->MakeClientTransport(); return std::make_pair(std::move(client_transport), std::move(server_transport)); diff --git a/src/core/ext/transport/inproc/inproc_transport.h b/src/core/ext/transport/inproc/inproc_transport.h index 676b5f1fa32..46dc9b540f1 100644 --- a/src/core/ext/transport/inproc/inproc_transport.h +++ b/src/core/ext/transport/inproc/inproc_transport.h @@ -30,7 +30,7 @@ extern grpc_core::TraceFlag grpc_inproc_trace; namespace grpc_core { std::pair, OrphanablePtr> -MakeInProcessTransportPair(); +MakeInProcessTransportPair(const ChannelArgs& server_channel_args); } diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc index 9b28a321db1..c428bac0006 100644 --- a/src/core/lib/channel/channel_stack.cc +++ b/src/core/lib/channel/channel_stack.cc @@ -305,13 +305,6 @@ grpc_core::NextPromiseFactory ClientNext(grpc_channel_element* elem) { }; } -grpc_core::NextPromiseFactory ServerNext(grpc_channel_element* elem) { - return [elem](grpc_core::CallArgs args) { - return elem->filter->make_call_promise(elem, std::move(args), - ServerNext(elem - 1)); - }; -} - } // namespace grpc_core::ArenaPromise @@ -319,12 +312,6 @@ grpc_channel_stack::MakeClientCallPromise(grpc_core::CallArgs call_args) { return ClientNext(grpc_channel_stack_element(this, 0))(std::move(call_args)); } -grpc_core::ArenaPromise -grpc_channel_stack::MakeServerCallPromise(grpc_core::CallArgs call_args) { - return ServerNext(grpc_channel_stack_element(this, this->count - 1))( - std::move(call_args)); -} - void grpc_channel_stack::InitClientCallSpine( grpc_core::CallSpineInterface* call) { for (size_t i = 0; i < count; i++) { @@ -338,19 +325,6 @@ void grpc_channel_stack::InitClientCallSpine( } } -void grpc_channel_stack::InitServerCallSpine( - grpc_core::CallSpineInterface* call) { - for (size_t i = 0; i < count; i++) { - auto* elem = grpc_channel_stack_element(this, count - 1 - i); - if (elem->filter->init_call == nullptr) { - grpc_core::Crash( - absl::StrCat("Filter '", elem->filter->name, - "' does not support the call-v3 interface")); - } - elem->filter->init_call(elem, call); - } -} - void grpc_call_log_op(const char* file, int line, gpr_log_severity severity, grpc_call_element* elem, grpc_transport_stream_op_batch* op) { diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index affd34a4191..030173fcd31 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -241,7 +241,6 @@ struct grpc_channel_stack { MakeServerCallPromise(grpc_core::CallArgs call_args); void InitClientCallSpine(grpc_core::CallSpineInterface* call); - void InitServerCallSpine(grpc_core::CallSpineInterface* call); }; // A call stack tracks a set of related filters for one call, and guarantees diff --git a/src/core/lib/experiments/experiments.cc b/src/core/lib/experiments/experiments.cc index c5e2d3fb3b9..4bf01759fc2 100644 --- a/src/core/lib/experiments/experiments.cc +++ b/src/core/lib/experiments/experiments.cc @@ -88,23 +88,17 @@ const char* const additional_constraints_promise_based_client_call = "{}"; const uint8_t required_experiments_promise_based_client_call[] = { static_cast(grpc_core::kExperimentIdEventEngineClient), static_cast(grpc_core::kExperimentIdEventEngineListener)}; -const char* const description_promise_based_server_call = - "If set, use the new gRPC promise based call code when it's appropriate " - "(ie when all filters in a stack are promise based)"; -const char* const additional_constraints_promise_based_server_call = "{}"; const char* const description_chaotic_good = "If set, enable the chaotic good load transport (this is mostly here for " "testing)"; const char* const additional_constraints_chaotic_good = "{}"; const uint8_t required_experiments_chaotic_good[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_promise_based_inproc_transport = "Use promises for the in-process transport."; const char* const additional_constraints_promise_based_inproc_transport = "{}"; const uint8_t required_experiments_promise_based_inproc_transport[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_rstpit = "On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short " "duration"; @@ -184,15 +178,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"promise_based_client_call", description_promise_based_client_call, additional_constraints_promise_based_client_call, required_experiments_promise_based_client_call, 2, false, true}, - {"promise_based_server_call", description_promise_based_server_call, - additional_constraints_promise_based_server_call, nullptr, 0, false, true}, {"chaotic_good", description_chaotic_good, - additional_constraints_chaotic_good, required_experiments_chaotic_good, 2, + additional_constraints_chaotic_good, required_experiments_chaotic_good, 1, false, true}, {"promise_based_inproc_transport", description_promise_based_inproc_transport, additional_constraints_promise_based_inproc_transport, - required_experiments_promise_based_inproc_transport, 2, false, false}, + required_experiments_promise_based_inproc_transport, 1, false, false}, {"rstpit", description_rstpit, additional_constraints_rstpit, nullptr, 0, false, true}, {"schedule_cancellation_over_write", @@ -288,23 +280,17 @@ const char* const additional_constraints_promise_based_client_call = "{}"; const uint8_t required_experiments_promise_based_client_call[] = { static_cast(grpc_core::kExperimentIdEventEngineClient), static_cast(grpc_core::kExperimentIdEventEngineListener)}; -const char* const description_promise_based_server_call = - "If set, use the new gRPC promise based call code when it's appropriate " - "(ie when all filters in a stack are promise based)"; -const char* const additional_constraints_promise_based_server_call = "{}"; const char* const description_chaotic_good = "If set, enable the chaotic good load transport (this is mostly here for " "testing)"; const char* const additional_constraints_chaotic_good = "{}"; const uint8_t required_experiments_chaotic_good[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_promise_based_inproc_transport = "Use promises for the in-process transport."; const char* const additional_constraints_promise_based_inproc_transport = "{}"; const uint8_t required_experiments_promise_based_inproc_transport[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_rstpit = "On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short " "duration"; @@ -384,15 +370,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"promise_based_client_call", description_promise_based_client_call, additional_constraints_promise_based_client_call, required_experiments_promise_based_client_call, 2, false, true}, - {"promise_based_server_call", description_promise_based_server_call, - additional_constraints_promise_based_server_call, nullptr, 0, false, true}, {"chaotic_good", description_chaotic_good, - additional_constraints_chaotic_good, required_experiments_chaotic_good, 2, + additional_constraints_chaotic_good, required_experiments_chaotic_good, 1, false, true}, {"promise_based_inproc_transport", description_promise_based_inproc_transport, additional_constraints_promise_based_inproc_transport, - required_experiments_promise_based_inproc_transport, 2, false, false}, + required_experiments_promise_based_inproc_transport, 1, false, false}, {"rstpit", description_rstpit, additional_constraints_rstpit, nullptr, 0, false, true}, {"schedule_cancellation_over_write", @@ -488,23 +472,17 @@ const char* const additional_constraints_promise_based_client_call = "{}"; const uint8_t required_experiments_promise_based_client_call[] = { static_cast(grpc_core::kExperimentIdEventEngineClient), static_cast(grpc_core::kExperimentIdEventEngineListener)}; -const char* const description_promise_based_server_call = - "If set, use the new gRPC promise based call code when it's appropriate " - "(ie when all filters in a stack are promise based)"; -const char* const additional_constraints_promise_based_server_call = "{}"; const char* const description_chaotic_good = "If set, enable the chaotic good load transport (this is mostly here for " "testing)"; const char* const additional_constraints_chaotic_good = "{}"; const uint8_t required_experiments_chaotic_good[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_promise_based_inproc_transport = "Use promises for the in-process transport."; const char* const additional_constraints_promise_based_inproc_transport = "{}"; const uint8_t required_experiments_promise_based_inproc_transport[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_rstpit = "On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short " "duration"; @@ -584,15 +562,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"promise_based_client_call", description_promise_based_client_call, additional_constraints_promise_based_client_call, required_experiments_promise_based_client_call, 2, false, true}, - {"promise_based_server_call", description_promise_based_server_call, - additional_constraints_promise_based_server_call, nullptr, 0, false, true}, {"chaotic_good", description_chaotic_good, - additional_constraints_chaotic_good, required_experiments_chaotic_good, 2, + additional_constraints_chaotic_good, required_experiments_chaotic_good, 1, false, true}, {"promise_based_inproc_transport", description_promise_based_inproc_transport, additional_constraints_promise_based_inproc_transport, - required_experiments_promise_based_inproc_transport, 2, false, false}, + required_experiments_promise_based_inproc_transport, 1, false, false}, {"rstpit", description_rstpit, additional_constraints_rstpit, nullptr, 0, false, true}, {"schedule_cancellation_over_write", diff --git a/src/core/lib/experiments/experiments.h b/src/core/lib/experiments/experiments.h index 65fb7ebfa80..16220be2591 100644 --- a/src/core/lib/experiments/experiments.h +++ b/src/core/lib/experiments/experiments.h @@ -79,7 +79,6 @@ inline bool IsPendingQueueCapEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW inline bool IsPickFirstNewEnabled() { return true; } inline bool IsPromiseBasedClientCallEnabled() { return false; } -inline bool IsPromiseBasedServerCallEnabled() { return false; } inline bool IsChaoticGoodEnabled() { return false; } inline bool IsPromiseBasedInprocTransportEnabled() { return false; } inline bool IsRstpitEnabled() { return false; } @@ -119,7 +118,6 @@ inline bool IsPendingQueueCapEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW inline bool IsPickFirstNewEnabled() { return true; } inline bool IsPromiseBasedClientCallEnabled() { return false; } -inline bool IsPromiseBasedServerCallEnabled() { return false; } inline bool IsChaoticGoodEnabled() { return false; } inline bool IsPromiseBasedInprocTransportEnabled() { return false; } inline bool IsRstpitEnabled() { return false; } @@ -159,7 +157,6 @@ inline bool IsPendingQueueCapEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW inline bool IsPickFirstNewEnabled() { return true; } inline bool IsPromiseBasedClientCallEnabled() { return false; } -inline bool IsPromiseBasedServerCallEnabled() { return false; } inline bool IsChaoticGoodEnabled() { return false; } inline bool IsPromiseBasedInprocTransportEnabled() { return false; } inline bool IsRstpitEnabled() { return false; } @@ -195,7 +192,6 @@ enum ExperimentIds { kExperimentIdPendingQueueCap, kExperimentIdPickFirstNew, kExperimentIdPromiseBasedClientCall, - kExperimentIdPromiseBasedServerCall, kExperimentIdChaoticGood, kExperimentIdPromiseBasedInprocTransport, kExperimentIdRstpit, @@ -277,10 +273,6 @@ inline bool IsPickFirstNewEnabled() { inline bool IsPromiseBasedClientCallEnabled() { return IsExperimentEnabled(kExperimentIdPromiseBasedClientCall); } -#define GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL -inline bool IsPromiseBasedServerCallEnabled() { - return IsExperimentEnabled(kExperimentIdPromiseBasedServerCall); -} #define GRPC_EXPERIMENT_IS_INCLUDED_CHAOTIC_GOOD inline bool IsChaoticGoodEnabled() { return IsExperimentEnabled(kExperimentIdChaoticGood); diff --git a/src/core/lib/experiments/experiments.yaml b/src/core/lib/experiments/experiments.yaml index 0712c8afd85..0e00f5c4d68 100644 --- a/src/core/lib/experiments/experiments.yaml +++ b/src/core/lib/experiments/experiments.yaml @@ -64,7 +64,7 @@ If set, enable the chaotic good load transport (this is mostly here for testing) expiry: 2024/09/09 owner: ctiller@google.com - requires: [promise_based_client_call, promise_based_server_call] + requires: [promise_based_client_call] test_tags: [core_end2end_test] - name: client_privacy description: @@ -170,14 +170,7 @@ owner: ctiller@google.com test_tags: [] allow_in_fuzzing_config: false # experiment currently crashes if enabled - requires: [promise_based_client_call, promise_based_server_call] -- name: promise_based_server_call - description: - If set, use the new gRPC promise based call code when it's appropriate - (ie when all filters in a stack are promise based) - expiry: 2024/06/14 - owner: ctiller@google.com - test_tags: ["core_end2end_test", "logging_test"] + requires: [promise_based_client_call] - name: rstpit description: On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short duration diff --git a/src/core/lib/experiments/rollouts.yaml b/src/core/lib/experiments/rollouts.yaml index f9d968d62a2..97018a672cd 100644 --- a/src/core/lib/experiments/rollouts.yaml +++ b/src/core/lib/experiments/rollouts.yaml @@ -94,8 +94,6 @@ ios: broken windows: broken posix: false -- name: promise_based_server_call - default: false - name: rstpit default: false - name: schedule_cancellation_over_write diff --git a/src/core/lib/promise/detail/promise_like.h b/src/core/lib/promise/detail/promise_like.h index a8b80172c22..8e73577675a 100644 --- a/src/core/lib/promise/detail/promise_like.h +++ b/src/core/lib/promise/detail/promise_like.h @@ -17,6 +17,7 @@ #include +#include "absl/functional/any_invocable.h" #include "absl/meta/type_traits.h" #include @@ -63,6 +64,10 @@ auto WrapInPoll(T&& x) -> decltype(PollWrapper::Wrap(std::forward(x))) { return PollWrapper::Wrap(std::forward(x)); } +// T -> T, const T& -> T +template +using RemoveCVRef = absl::remove_cv_t>; + template class PromiseLike; @@ -73,7 +78,7 @@ template class PromiseLike::type>::value>> { private: - GPR_NO_UNIQUE_ADDRESS F f_; + GPR_NO_UNIQUE_ADDRESS RemoveCVRef f_; public: // NOLINTNEXTLINE - internal detail that drastically simplifies calling code. @@ -82,10 +87,6 @@ class PromiseLike::Type; }; -// T -> T, const T& -> T -template -using RemoveCVRef = absl::remove_cv_t>; - } // namespace promise_detail } // namespace grpc_core diff --git a/src/core/lib/promise/status_flag.h b/src/core/lib/promise/status_flag.h index 38d4cf5b720..132b2079c07 100644 --- a/src/core/lib/promise/status_flag.h +++ b/src/core/lib/promise/status_flag.h @@ -171,6 +171,8 @@ class ValueOrFailure { T& value() { return value_.value(); } const T& operator*() const { return *value_; } T& operator*() { return *value_; } + const T* operator->() const { return &*value_; } + T* operator->() { return &*value_; } bool operator==(const ValueOrFailure& other) const { return value_ == other.value_; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 6d2457dba2d..0d268a21572 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -125,7 +125,7 @@ using GrpcClosure = Closure; Call::ParentCall* Call::GetOrCreateParentCall() { ParentCall* p = parent_call_.load(std::memory_order_acquire); if (p == nullptr) { - p = arena_->New(); + p = arena()->New(); ParentCall* expected = nullptr; if (!parent_call_.compare_exchange_strong(expected, p, std::memory_order_release, @@ -244,28 +244,6 @@ void Call::PropagateCancellationToChildren() { } } -char* Call::GetPeer() { - Slice peer_slice = GetPeerString(); - if (!peer_slice.empty()) { - absl::string_view peer_string_view = peer_slice.as_string_view(); - char* peer_string = - static_cast(gpr_malloc(peer_string_view.size() + 1)); - memcpy(peer_string, peer_string_view.data(), peer_string_view.size()); - peer_string[peer_string_view.size()] = '\0'; - return peer_string; - } - char* peer_string = grpc_channel_get_target(channel_->c_ptr()); - if (peer_string != nullptr) return peer_string; - return gpr_strdup("unknown"); -} - -void Call::DeleteThis() { - RefCountedPtr channel = std::move(channel_); - Arena* arena = arena_; - this->~Call(); - channel->DestroyArena(arena); -} - void Call::PrepareOutgoingInitialMetadata(const grpc_op& op, grpc_metadata_batch& md) { // TODO(juanlishen): If the user has already specified a compression @@ -280,7 +258,7 @@ void Call::PrepareOutgoingInitialMetadata(const grpc_op& op, op.data.send_initial_metadata.maybe_compression_level.level; level_set = true; } else { - const grpc_compression_options copts = channel()->compression_options(); + const grpc_compression_options copts = compression_options(); if (copts.default_level.is_set) { level_set = true; effective_compression_level = copts.default_level.level; @@ -312,13 +290,12 @@ void Call::ProcessIncomingInitialMetadata(grpc_metadata_batch& md) { md.Take(GrpcAcceptEncodingMetadata()) .value_or(CompressionAlgorithmSet{GRPC_COMPRESS_NONE}); - const grpc_compression_options compression_options = - channel_->compression_options(); + const grpc_compression_options copts = compression_options(); const grpc_compression_algorithm compression_algorithm = incoming_compression_algorithm_; - if (GPR_UNLIKELY(!CompressionAlgorithmSet::FromUint32( - compression_options.enabled_algorithms_bitset) - .IsSet(compression_algorithm))) { + if (GPR_UNLIKELY( + !CompressionAlgorithmSet::FromUint32(copts.enabled_algorithms_bitset) + .IsSet(compression_algorithm))) { // check if algorithm is supported by current channel config HandleCompressionAlgorithmDisabled(compression_algorithm); } @@ -368,22 +345,20 @@ void Call::UpdateDeadline(Timestamp deadline) { StatusIntProperty::kRpcStatus, GRPC_STATUS_DEADLINE_EXCEEDED)); return; } - auto* const event_engine = channel()->event_engine(); if (deadline_ != Timestamp::InfFuture()) { - if (!event_engine->Cancel(deadline_task_)) return; + if (!event_engine_->Cancel(deadline_task_)) return; } else { InternalRef("deadline"); } deadline_ = deadline; - deadline_task_ = event_engine->RunAfter(deadline - Timestamp::Now(), this); + deadline_task_ = event_engine_->RunAfter(deadline - Timestamp::Now(), this); } void Call::ResetDeadline() { { MutexLock lock(&deadline_mu_); if (deadline_ == Timestamp::InfFuture()) return; - auto* const event_engine = channel()->event_engine(); - if (!event_engine->Cancel(deadline_task_)) return; + if (!event_engine_->Cancel(deadline_task_)) return; deadline_ = Timestamp::InfFuture(); } InternalUnref("deadline[reset]"); @@ -398,11 +373,69 @@ void Call::Run() { InternalUnref("deadline[run]"); } +/////////////////////////////////////////////////////////////////////////////// +// ChannelBasedCall +// TODO(ctiller): once we remove the v2 client code this can be folded into +// FilterStackCall + +class ChannelBasedCall : public Call { + protected: + ChannelBasedCall(Arena* arena, bool is_client, Timestamp send_deadline, + RefCountedPtr channel) + : Call(is_client, send_deadline, channel->event_engine()), + arena_(arena), + channel_(std::move(channel)) { + DCHECK_NE(arena_, nullptr); + } + + Arena* arena() final { return arena_; } + + char* GetPeer() final { + Slice peer_slice = GetPeerString(); + if (!peer_slice.empty()) { + absl::string_view peer_string_view = peer_slice.as_string_view(); + char* peer_string = + static_cast(gpr_malloc(peer_string_view.size() + 1)); + memcpy(peer_string, peer_string_view.data(), peer_string_view.size()); + peer_string[peer_string_view.size()] = '\0'; + return peer_string; + } + char* peer_string = grpc_channel_get_target(channel_->c_ptr()); + if (peer_string != nullptr) return peer_string; + return gpr_strdup("unknown"); + } + + grpc_event_engine::experimental::EventEngine* event_engine() const override { + return channel_->event_engine(); + } + + grpc_compression_options compression_options() override { + return channel_->compression_options(); + } + + void DeleteThis() { + RefCountedPtr channel = std::move(channel_); + Arena* arena = arena_; + this->~ChannelBasedCall(); + channel->DestroyArena(arena); + } + + Channel* channel() const { return channel_.get(); } + + protected: + // Non-virtual arena accessor -- needed by PipeBasedCall + Arena* GetArena() { return arena_; } + + private: + Arena* const arena_; + RefCountedPtr channel_; +}; + /////////////////////////////////////////////////////////////////////////////// // FilterStackCall // To be removed once promise conversion is complete -class FilterStackCall final : public Call { +class FilterStackCall final : public ChannelBasedCall { public: ~FilterStackCall() override { for (int i = 0; i < GRPC_CONTEXT_COUNT; ++i) { @@ -431,10 +464,6 @@ class FilterStackCall final : public Call { GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(*this))); } - grpc_event_engine::experimental::EventEngine* event_engine() const override { - return channel()->event_engine(); - } - grpc_call_element* call_elem(size_t idx) { return grpc_call_stack_element(call_stack(), idx); } @@ -570,8 +599,8 @@ class FilterStackCall final : public Call { }; FilterStackCall(Arena* arena, const grpc_call_create_args& args) - : Call(arena, args.server_transport_data == nullptr, args.send_deadline, - args.channel->Ref()), + : ChannelBasedCall(arena, args.server_transport_data == nullptr, + args.send_deadline, args.channel->Ref()), cq_(args.cq), stream_op_payload_(context_) { context_[GRPC_CONTEXT_CALL].value = this; @@ -1874,15 +1903,15 @@ bool ValidateMetadata(size_t count, grpc_metadata* metadata) { // PromiseBasedCall // Will be folded into Call once the promise conversion is done -class BasicPromiseBasedCall : public Call, public Party { +class BasicPromiseBasedCall : public ChannelBasedCall, public Party { public: using Call::arena; BasicPromiseBasedCall(Arena* arena, uint32_t initial_external_refs, uint32_t initial_internal_refs, const grpc_call_create_args& args) - : Call(arena, args.server_transport_data == nullptr, args.send_deadline, - args.channel->Ref()), + : ChannelBasedCall(arena, args.server_transport_data == nullptr, + args.send_deadline, args.channel->Ref()), Party(initial_internal_refs), external_refs_(initial_external_refs), cq_(args.cq) { @@ -1903,7 +1932,6 @@ class BasicPromiseBasedCall : public Call, public Party { virtual void OrphanCall() = 0; - virtual ServerCallContext* server_call_context() { return nullptr; } void SetCompletionQueue(grpc_completion_queue* cq) final { cq_ = cq; GRPC_CQ_INTERNAL_REF(cq, "bind"); @@ -2533,10 +2561,6 @@ void CallContext::IncrementRefCount(const char* reason) { void CallContext::Unref(const char* reason) { call_->InternalUnref(reason); } -ServerCallContext* CallContext::server_call_context() { - return call_->server_call_context(); -} - RefCountedPtr CallContext::MakeCallSpine( CallArgs call_args) { return call_->MakeCallSpine(std::move(call_args)); @@ -2780,12 +2804,12 @@ class ClientPromiseBasedCall final : public PromiseBasedCall { void PublishInitialMetadata(ServerMetadata* metadata); ClientMetadataHandle send_initial_metadata_; - Pipe server_initial_metadata_{arena()}; + Pipe server_initial_metadata_{GetArena()}; Latch server_trailing_metadata_; Latch cancel_error_; Latch polling_entity_; - Pipe client_to_server_messages_{arena()}; - Pipe server_to_client_messages_{arena()}; + Pipe client_to_server_messages_{GetArena()}; + Pipe server_to_client_messages_{GetArena()}; bool is_trailers_only_ = false; bool scheduled_receive_status_ = false; bool scheduled_send_close_ = false; @@ -3092,242 +3116,7 @@ void ClientPromiseBasedCall::StartRecvStatusOnClient( #endif /////////////////////////////////////////////////////////////////////////////// -// ServerPromiseBasedCall - -#ifdef GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL - -class ServerPromiseBasedCall final : public PromiseBasedCall, - public ServerCallContext { - public: - ServerPromiseBasedCall(Arena* arena, grpc_call_create_args* args); - - void OrphanCall() override {} - void CancelWithError(grpc_error_handle) override; - grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag, - bool is_notify_tag_closure) override; - bool is_trailers_only() const override { - Crash("is_trailers_only not implemented for server calls"); - } - absl::string_view GetServerAuthority() const override { - const Slice* authority_metadata = - client_initial_metadata_->get_pointer(HttpAuthorityMetadata()); - if (authority_metadata == nullptr) return ""; - return authority_metadata->as_string_view(); - } - - // Polling order for the server promise stack: - // - // │ ┌───────────────────────────────────────┐ - // │ │ ServerPromiseBasedCall ├──► Lifetime management - // │ ├───────────────────────────────────────┤ - // │ │ ConnectedChannel ├─┐ - // │ ├───────────────────────────────────────┤ └► Interactions with the - // │ │ ... closest to transport filter │ transport - send/recv msgs - // │ ├───────────────────────────────────────┤ and metadata, call phase - // │ │ ... │ ordering - // │ ├───────────────────────────────────────┤ - // │ │ ... closest to app filter │ ┌► Request matching, initial - // │ ├───────────────────────────────────────┤ │ setup, publishing call to - // │ │ Server::ChannelData::MakeCallPromise ├─┘ application - // │ ├───────────────────────────────────────┤ - // │ │ MakeTopOfServerCallPromise ├──► Send trailing metadata - // ▼ └───────────────────────────────────────┘ - // Polling & - // instantiation - // order - - std::string DebugTag() const override { - return absl::StrFormat("SERVER_CALL[%p]: ", this); - } - - ServerCallContext* server_call_context() override { return this; } - - const void* server_stream_data() override { return server_transport_data_; } - void PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) override; - ArenaPromise MakeTopOfServerCallPromise( - CallArgs call_args, grpc_completion_queue* cq, - absl::FunctionRef publish) override; - - private: - class RecvCloseOpCancelState { - public: - // Request that receiver be filled in per - // grpc_op_recv_close_on_server. Returns true if the request can - // be fulfilled immediately. Returns false if the request will be - // fulfilled later. - bool ReceiveCloseOnServerOpStarted(int* receiver) { - uintptr_t state = state_.load(std::memory_order_acquire); - uintptr_t new_state; - do { - switch (state) { - case kUnset: - new_state = reinterpret_cast(receiver); - break; - case kFinishedWithFailure: - *receiver = 1; - return true; - case kFinishedWithSuccess: - *receiver = 0; - return true; - default: - Crash("Two threads offered ReceiveCloseOnServerOpStarted"); - } - } while (!state_.compare_exchange_weak(state, new_state, - std::memory_order_acq_rel, - std::memory_order_acquire)); - return false; - } - - // Mark the call as having completed. - // Returns true if this finishes a previous - // RequestReceiveCloseOnServer. - bool CompleteCallWithCancelledSetTo(bool cancelled) { - uintptr_t state = state_.load(std::memory_order_acquire); - uintptr_t new_state; - bool r; - do { - switch (state) { - case kUnset: - new_state = cancelled ? kFinishedWithFailure : kFinishedWithSuccess; - r = false; - break; - case kFinishedWithFailure: - return false; - case kFinishedWithSuccess: - Crash("unreachable"); - default: - new_state = cancelled ? kFinishedWithFailure : kFinishedWithSuccess; - r = true; - } - } while (!state_.compare_exchange_weak(state, new_state, - std::memory_order_acq_rel, - std::memory_order_acquire)); - if (r) *reinterpret_cast(state) = cancelled ? 1 : 0; - return r; - } - - std::string ToString() const { - auto state = state_.load(std::memory_order_relaxed); - switch (state) { - case kUnset: - return "Unset"; - case kFinishedWithFailure: - return "FinishedWithFailure"; - case kFinishedWithSuccess: - return "FinishedWithSuccess"; - default: - return absl::StrFormat("WaitingForReceiver(%p)", - reinterpret_cast(state)); - } - } - - private: - static constexpr uintptr_t kUnset = 0; - static constexpr uintptr_t kFinishedWithFailure = 1; - static constexpr uintptr_t kFinishedWithSuccess = 2; - // Holds one of kUnset, kFinishedWithFailure, or - // kFinishedWithSuccess OR an int* that wants to receive the - // final status. - std::atomic state_{kUnset}; - }; - - void CommitBatch(const grpc_op* ops, size_t nops, - const Completion& completion); - void Finish(ServerMetadataHandle result); - - ServerInterface* const server_; - const void* const server_transport_data_; - PipeSender* server_initial_metadata_ = nullptr; - PipeSender* server_to_client_messages_ = nullptr; - PipeReceiver* client_to_server_messages_ = nullptr; - Latch send_trailing_metadata_; - RecvCloseOpCancelState recv_close_op_cancel_state_; - ClientMetadataHandle client_initial_metadata_; - Completion recv_close_completion_; - std::atomic cancelled_{false}; -}; - -ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena, - grpc_call_create_args* args) - : PromiseBasedCall(arena, 0, *args), - server_(args->server), - server_transport_data_(args->server_transport_data) { - global_stats().IncrementServerCallsCreated(); - channelz::ServerNode* channelz_node = server_->channelz_node(); - if (channelz_node != nullptr) { - channelz_node->RecordCallStarted(); - } - ScopedContext activity_context(this); - // TODO(yashykt): In the future, we want to also enable stats and trace - // collecting from when the call is created at the transport. The idea is that - // the transport would create the call tracer and pass it in as part of the - // metadata. - // TODO(yijiem): OpenCensus and internal Census is still using this way to - // set server call tracer. We need to refactor them to stats plugins - // (including removing the client channel filters). - if (args->server != nullptr && - args->server->server_call_tracer_factory() != nullptr) { - auto* server_call_tracer = - args->server->server_call_tracer_factory()->CreateNewServerCallTracer( - arena, args->server->channel_args()); - if (server_call_tracer != nullptr) { - // Note that we are setting both - // GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE and - // GRPC_CONTEXT_CALL_TRACER as a matter of convenience. In the future - // promise-based world, we would just a single tracer object for each - // stack (call, subchannel_call, server_call.) - ContextSet(GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE, - server_call_tracer, nullptr); - ContextSet(GRPC_CONTEXT_CALL_TRACER, server_call_tracer, nullptr); - } - } - args->channel->channel_stack()->stats_plugin_group->AddServerCallTracers( - context()); - Spawn("server_promise", - channel()->channel_stack()->MakeServerCallPromise( - CallArgs{nullptr, ClientInitialMetadataOutstandingToken::Empty(), - nullptr, nullptr, nullptr, nullptr}), - [this](ServerMetadataHandle result) { Finish(std::move(result)); }); -} - -void ServerPromiseBasedCall::Finish(ServerMetadataHandle result) { - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] Finish: recv_close_state:%s result:%s", - DebugTag().c_str(), recv_close_op_cancel_state_.ToString().c_str(), - result->DebugString().c_str()); - } - const auto status = - result->get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN); - channelz::ServerNode* channelz_node = server_->channelz_node(); - if (channelz_node != nullptr) { - if (status == GRPC_STATUS_OK) { - channelz_node->RecordCallSucceeded(); - } else { - channelz_node->RecordCallFailed(); - } - } - bool was_cancelled = result->get(GrpcCallWasCancelled()).value_or(true); - if (recv_close_op_cancel_state_.CompleteCallWithCancelledSetTo( - was_cancelled)) { - FinishOpOnCompletion(&recv_close_completion_, - PendingOp::kReceiveCloseOnServer); - } - if (was_cancelled) set_failed_before_recv_message(); - if (server_initial_metadata_ != nullptr) { - server_initial_metadata_->Close(); - } - Slice message_slice; - if (Slice* message = result->get_pointer(GrpcMessageMetadata())) { - message_slice = message->Ref(); - } - AcceptTransportStatsFromContext(); - SetFinalizationStatus(status, std::move(message_slice)); - set_completed(); - ResetDeadline(); - PropagateCancellationToChildren(); -} +// CallSpine based Server Call grpc_call_error ValidateServerBatch(const grpc_op* ops, size_t nops) { BitSet<8> got_ops; @@ -3371,234 +3160,33 @@ grpc_call_error ValidateServerBatch(const grpc_op* ops, size_t nops) { return GRPC_CALL_OK; } -void ServerPromiseBasedCall::CommitBatch(const grpc_op* ops, size_t nops, - const Completion& completion) { - Party::BulkSpawner spawner(this); - for (size_t op_idx = 0; op_idx < nops; op_idx++) { - const grpc_op& op = ops[op_idx]; - switch (op.op) { - case GRPC_OP_SEND_INITIAL_METADATA: { - auto metadata = arena()->MakePooled(); - PrepareOutgoingInitialMetadata(op, *metadata); - CToMetadata(op.data.send_initial_metadata.metadata, - op.data.send_initial_metadata.count, metadata.get()); - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] Send initial metadata", - DebugTag().c_str()); - } - QueueSend(); - spawner.Spawn( - "call_send_initial_metadata", - [this, metadata = std::move(metadata)]() mutable { - EnactSend(); - return server_initial_metadata_->Push(std::move(metadata)); - }, - [this, - completion = AddOpToCompletion( - completion, PendingOp::kSendInitialMetadata)](bool r) mutable { - if (!r) { - set_failed_before_recv_message(); - FailCompletion(completion); - } - FinishOpOnCompletion(&completion, - PendingOp::kSendInitialMetadata); - }); - } break; - case GRPC_OP_SEND_MESSAGE: - StartSendMessage(op, completion, server_to_client_messages_, spawner); - break; - case GRPC_OP_RECV_MESSAGE: - if (cancelled_.load(std::memory_order_relaxed)) { - set_failed_before_recv_message(); - FailCompletion(completion); - break; - } - StartRecvMessage( - op, completion, []() { return []() { return Empty{}; }; }, - client_to_server_messages_, true, spawner); - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: { - auto metadata = arena()->MakePooled(); - CToMetadata(op.data.send_status_from_server.trailing_metadata, - op.data.send_status_from_server.trailing_metadata_count, - metadata.get()); - metadata->Set(GrpcStatusMetadata(), - op.data.send_status_from_server.status); - if (auto* details = op.data.send_status_from_server.status_details) { - // TODO(ctiller): this should not be a copy, but we have callers that - // allocate and pass in a slice created with - // grpc_slice_from_static_string and then delete the string after - // passing it in, which shouldn't be a supported API. - metadata->Set(GrpcMessageMetadata(), - Slice(grpc_slice_copy(*details))); - } - spawner.Spawn( - "call_send_status_from_server", - [this, metadata = std::move(metadata)]() mutable { - bool r = true; - if (send_trailing_metadata_.is_set()) { - r = false; - } else { - send_trailing_metadata_.Set(std::move(metadata)); - } - return Map(WaitForSendingStarted(), [this, r](Empty) { - server_initial_metadata_->Close(); - server_to_client_messages_->Close(); - return r; - }); - }, - [this, completion = AddOpToCompletion( - completion, PendingOp::kSendStatusFromServer)]( - bool ok) mutable { - if (!ok) { - set_failed_before_recv_message(); - FailCompletion(completion); - } - FinishOpOnCompletion(&completion, - PendingOp::kSendStatusFromServer); - }); - } break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] StartBatch: RecvClose %s", - DebugTag().c_str(), - recv_close_op_cancel_state_.ToString().c_str()); - } - ForceCompletionSuccess(completion); - recv_close_completion_ = - AddOpToCompletion(completion, PendingOp::kReceiveCloseOnServer); - if (recv_close_op_cancel_state_.ReceiveCloseOnServerOpStarted( - op.data.recv_close_on_server.cancelled)) { - FinishOpOnCompletion(&recv_close_completion_, - PendingOp::kReceiveCloseOnServer); - } - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - case GRPC_OP_RECV_INITIAL_METADATA: - abort(); // unreachable - } - } -} - -grpc_call_error ServerPromiseBasedCall::StartBatch(const grpc_op* ops, - size_t nops, - void* notify_tag, - bool is_notify_tag_closure) { - if (nops == 0) { - EndOpImmediately(cq(), notify_tag, is_notify_tag_closure); - return GRPC_CALL_OK; - } - const grpc_call_error validation_result = ValidateServerBatch(ops, nops); - if (validation_result != GRPC_CALL_OK) { - return validation_result; - } - Completion completion = - StartCompletion(notify_tag, is_notify_tag_closure, ops); - CommitBatch(ops, nops, completion); - FinishOpOnCompletion(&completion, PendingOp::kStartingBatch); - return GRPC_CALL_OK; -} - -void ServerPromiseBasedCall::CancelWithError(absl::Status error) { - cancelled_.store(true, std::memory_order_relaxed); - Spawn( - "cancel_with_error", - [this, error = std::move(error)]() { - if (!send_trailing_metadata_.is_set()) { - auto md = ServerMetadataFromStatus(error); - md->Set(GrpcCallWasCancelled(), true); - send_trailing_metadata_.Set(std::move(md)); - } - if (server_to_client_messages_ != nullptr) { - server_to_client_messages_->Close(); - } - if (server_initial_metadata_ != nullptr) { - server_initial_metadata_->Close(); - } - return Empty{}; - }, - [](Empty) {}); -} -#endif - -#ifdef GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL -void ServerPromiseBasedCall::PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) { - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] PublishInitialMetadata: %s", DebugTag().c_str(), - metadata->DebugString().c_str()); - } - PublishMetadataArray(metadata.get(), publish_initial_metadata, false); - client_initial_metadata_ = std::move(metadata); -} - -ArenaPromise -ServerPromiseBasedCall::MakeTopOfServerCallPromise( - CallArgs call_args, grpc_completion_queue* cq, - absl::FunctionRef publish) { - SetCompletionQueue(cq); - call_args.polling_entity->Set( - grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq))); - server_to_client_messages_ = call_args.server_to_client_messages; - client_to_server_messages_ = call_args.client_to_server_messages; - server_initial_metadata_ = call_args.server_initial_metadata; - absl::optional deadline = - client_initial_metadata_->get(GrpcTimeoutMetadata()); - if (deadline.has_value()) { - set_send_deadline(*deadline); - UpdateDeadline(*deadline); - } - ProcessIncomingInitialMetadata(*client_initial_metadata_); - ExternalRef(); - publish(c_ptr()); - return Seq(server_to_client_messages_->AwaitClosed(), - send_trailing_metadata_.Wait()); -} - -/////////////////////////////////////////////////////////////////////////////// -// CallSpine based Server Call - -class ServerCallSpine final : public PipeBasedCallSpine, - public ServerCallContext, - public BasicPromiseBasedCall { +class ServerCall final : public Call, public DualRefCounted { public: - ServerCallSpine(ClientMetadataHandle client_initial_metadata, - ServerInterface* server, Channel* channel, Arena* arena); - - // CallSpineInterface - Pipe& client_initial_metadata() override { - return client_initial_metadata_; - } - Pipe& server_initial_metadata() override { - return server_initial_metadata_; - } - Pipe& client_to_server_messages() override { - return client_to_server_messages_; - } - Pipe& server_to_client_messages() override { - return server_to_client_messages_; + ServerCall(ClientMetadataHandle client_initial_metadata, + CallHandler call_handler, ServerInterface* server, + grpc_completion_queue* cq) + : Call(false, + client_initial_metadata->get(GrpcTimeoutMetadata()) + .value_or(Timestamp::InfFuture()), + call_handler.event_engine()), + call_handler_(std::move(call_handler)), + client_initial_metadata_stored_(std::move(client_initial_metadata)), + cq_(cq), + server_(server) { + call_handler_.legacy_context()[GRPC_CONTEXT_CALL].value = + static_cast(this); + global_stats().IncrementServerCallsCreated(); } - Latch& cancel_latch() override { return cancel_latch_; } - Latch& was_cancelled_latch() override { return was_cancelled_latch_; } - Party& party() override { return *this; } - Arena* arena() override { return BasicPromiseBasedCall::arena(); } - void IncrementRefCount() override { InternalRef("CallSpine"); } - void Unref() override { InternalUnref("CallSpine"); } - // PromiseBasedCall - void OrphanCall() override { - ResetDeadline(); - CancelWithError(absl::CancelledError()); - } void CancelWithError(grpc_error_handle error) override { - SpawnInfallible("CancelWithError", [this, error = std::move(error)] { - auto status = ServerMetadataFromStatus(error); - status->Set(GrpcCallWasCancelled(), true); - PushServerTrailingMetadata(std::move(status)); - return Empty{}; - }); + call_handler_.SpawnInfallible( + "CancelWithError", + [self = WeakRefAsSubclass(), error = std::move(error)] { + auto status = ServerMetadataFromStatus(error); + status->Set(GrpcCallWasCancelled(), true); + self->call_handler_.PushServerTrailingMetadata(std::move(status)); + return Empty{}; + }); } bool is_trailers_only() const override { Crash("is_trailers_only not implemented for server calls"); @@ -3609,102 +3197,78 @@ class ServerCallSpine final : public PipeBasedCallSpine, grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag, bool is_notify_tag_closure) override; - bool Completed() final { Crash("unimplemented"); } - bool failed_before_recv_message() const final { Crash("unimplemented"); } + Arena* arena() override { return call_handler_.arena(); } - ServerCallContext* server_call_context() override { return this; } - const void* server_stream_data() override { Crash("unimplemented"); } - void PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) override; - ArenaPromise MakeTopOfServerCallPromise( - CallArgs, grpc_completion_queue*, - absl::FunctionRef) override { - Crash("unimplemented"); + grpc_event_engine::experimental::EventEngine* event_engine() const override { + return call_handler_.event_engine(); } - void V2HackToStartCallWithoutACallFilterStack() override {} + void ExternalRef() override { Ref().release(); } + void ExternalUnref() override { Unref(); } + void InternalRef(const char*) override { WeakRef().release(); } + void InternalUnref(const char*) override { WeakUnref(); } - ClientMetadata& UnprocessedClientInitialMetadata() override { - Crash("not for v2"); + void Orphaned() override { + // TODO(ctiller): only when we're not already finished + CancelWithError(absl::CancelledError()); } - bool RunParty() override { - ScopedContext ctx(this); - return Party::RunParty(); + void ContextSet(grpc_context_index elem, void* value, + void (*destroy)(void*)) override { + call_handler_.legacy_context()[elem] = + grpc_call_context_element{value, destroy}; + } + + void* ContextGet(grpc_context_index elem) const override { + return call_handler_.legacy_context()[elem].value; + } + + void SetCompletionQueue(grpc_completion_queue*) override { + Crash("unimplemented"); + } + + grpc_compression_options compression_options() override { + return server_->compression_options(); } + grpc_call_stack* call_stack() override { return nullptr; } + + char* GetPeer() override { + Slice peer_slice = GetPeerString(); + if (!peer_slice.empty()) { + absl::string_view peer_string_view = peer_slice.as_string_view(); + char* peer_string = + static_cast(gpr_malloc(peer_string_view.size() + 1)); + memcpy(peer_string, peer_string_view.data(), peer_string_view.size()); + peer_string[peer_string_view.size()] = '\0'; + return peer_string; + } + return gpr_strdup("unknown"); + } + + bool Completed() final { Crash("unimplemented"); } + bool failed_before_recv_message() const final { Crash("unimplemented"); } + private: void CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag, bool is_notify_tag_closure); - StatusFlag FinishRecvMessage(NextResult result); + StatusFlag FinishRecvMessage( + ValueOrFailure> result); - std::string DebugTag() const override { - return absl::StrFormat("SERVER_CALL_SPINE[%p]: ", this); - } - - // Initial metadata from client to server - Pipe client_initial_metadata_; - // Initial metadata from server to client - Pipe server_initial_metadata_; - // Messages travelling from the application to the transport. - Pipe client_to_server_messages_; - // Messages travelling from the transport to the application. - Pipe server_to_client_messages_; - // Latch that can be set to terminate the call - Latch cancel_latch_; - Latch was_cancelled_latch_; + std::string DebugTag() { return absl::StrFormat("SERVER_CALL[%p]: ", this); } + + CallHandler call_handler_; grpc_byte_buffer** recv_message_ = nullptr; ClientMetadataHandle client_initial_metadata_stored_; + grpc_completion_queue* const cq_; + ServerInterface* const server_; }; -ServerCallSpine::ServerCallSpine(ClientMetadataHandle client_initial_metadata, - ServerInterface* server, Channel* channel, - Arena* arena) - : BasicPromiseBasedCall(arena, 0, 1, - [channel, server]() -> grpc_call_create_args { - grpc_call_create_args args; - args.channel = channel->Ref(); - args.server = server; - args.parent = nullptr; - args.propagation_mask = 0; - args.cq = nullptr; - args.pollset_set_alternative = nullptr; - args.server_transport_data = - &args; // Arbitrary non-null pointer - args.send_deadline = Timestamp::InfFuture(); - return args; - }()), - client_initial_metadata_(arena), - server_initial_metadata_(arena), - client_to_server_messages_(arena), - server_to_client_messages_(arena) { - global_stats().IncrementServerCallsCreated(); - ScopedContext ctx(this); - channel->channel_stack()->InitServerCallSpine(this); - SpawnGuarded("push_client_initial_metadata", - [this, md = std::move(client_initial_metadata)]() mutable { - return Map(client_initial_metadata_.sender.Push(std::move(md)), - [](bool r) { return StatusFlag(r); }); - }); -} - -void ServerCallSpine::PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) { - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] PublishInitialMetadata: %s", DebugTag().c_str(), - metadata->DebugString().c_str()); - } - PublishMetadataArray(metadata.get(), publish_initial_metadata, false); - client_initial_metadata_stored_ = std::move(metadata); -} - -grpc_call_error ServerCallSpine::StartBatch(const grpc_op* ops, size_t nops, - void* notify_tag, - bool is_notify_tag_closure) { +grpc_call_error ServerCall::StartBatch(const grpc_op* ops, size_t nops, + void* notify_tag, + bool is_notify_tag_closure) { if (nops == 0) { - EndOpImmediately(cq(), notify_tag, is_notify_tag_closure); + EndOpImmediately(cq_, notify_tag, is_notify_tag_closure); return GRPC_CALL_OK; } const grpc_call_error validation_result = ValidateServerBatch(ops, nops); @@ -3716,63 +3280,86 @@ grpc_call_error ServerCallSpine::StartBatch(const grpc_op* ops, size_t nops, } namespace { -template +template class MaybeOpImpl { public: - using SetupResult = decltype(std::declval()(grpc_op())); using PromiseFactory = promise_detail::OncePromiseFactory; using Promise = typename PromiseFactory::Promise; - struct Dismissed {}; - using State = absl::variant; + static_assert(!std::is_same::value, + "PromiseFactory must return a promise"); + + MaybeOpImpl() : state_(State::kDismissed) {} + explicit MaybeOpImpl(SetupResult result) : state_(State::kPromiseFactory) { + Construct(&promise_factory_, std::move(result)); + } - // op_ is garbage but shouldn't be uninitialized - MaybeOpImpl() : state_(Dismissed{}), op_(GRPC_OP_RECV_STATUS_ON_CLIENT) {} - MaybeOpImpl(SetupResult result, grpc_op_type op) - : state_(PromiseFactory(std::move(result))), op_(op) {} + ~MaybeOpImpl() { + switch (state_) { + case State::kDismissed: + break; + case State::kPromiseFactory: + Destruct(&promise_factory_); + break; + case State::kPromise: + Destruct(&promise_); + break; + } + } MaybeOpImpl(const MaybeOpImpl&) = delete; MaybeOpImpl& operator=(const MaybeOpImpl&) = delete; - MaybeOpImpl(MaybeOpImpl&& other) noexcept - : state_(MoveState(other.state_)), op_(other.op_) {} - MaybeOpImpl& operator=(MaybeOpImpl&& other) noexcept { - op_ = other.op_; - if (absl::holds_alternative(state_)) { - state_.template emplace(); - return *this; + MaybeOpImpl(MaybeOpImpl&& other) noexcept : state_(other.state_) { + switch (state_) { + case State::kDismissed: + break; + case State::kPromiseFactory: + Construct(&promise_factory_, std::move(other.promise_factory_)); + break; + case State::kPromise: + Construct(&promise_, std::move(other.promise_)); + break; } - // Can't move after first poll => Promise is not an option - state_.template emplace( - std::move(absl::get(other.state_))); - return *this; } + MaybeOpImpl& operator=(MaybeOpImpl&& other) noexcept = delete; Poll operator()() { - if (absl::holds_alternative(state_)) return Success{}; - if (absl::holds_alternative(state_)) { - auto& factory = absl::get(state_); - auto promise = factory.Make(); - state_.template emplace(std::move(promise)); - } - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%sBeginPoll %s", - Activity::current()->DebugTag().c_str(), OpName(op_).c_str()); - } - auto& promise = absl::get(state_); - auto r = poll_cast(promise()); - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%sEndPoll %s --> %s", - Activity::current()->DebugTag().c_str(), OpName(op_).c_str(), + switch (state_) { + case State::kDismissed: + return Success{}; + case State::kPromiseFactory: { + auto promise = promise_factory_.Make(); + Destruct(&promise_factory_); + Construct(&promise_, std::move(promise)); + state_ = State::kPromise; + } + ABSL_FALLTHROUGH_INTENDED; + case State::kPromise: { + if (grpc_call_trace.enabled()) { + gpr_log(GPR_INFO, "%sBeginPoll %s", + Activity::current()->DebugTag().c_str(), OpName()); + } + auto r = poll_cast(promise_()); + if (grpc_call_trace.enabled()) { + gpr_log( + GPR_INFO, "%sEndPoll %s --> %s", + Activity::current()->DebugTag().c_str(), OpName(), r.pending() ? "PENDING" : (r.value().ok() ? "OK" : "FAILURE")); + } + return r; + } } - return r; + GPR_UNREACHABLE_CODE(return Pending{}); } private: - GPR_NO_UNIQUE_ADDRESS State state_; - GPR_NO_UNIQUE_ADDRESS grpc_op_type op_; + enum class State { + kDismissed, + kPromiseFactory, + kPromise, + }; - static std::string OpName(grpc_op_type op) { - switch (op) { + static const char* OpName() { + switch (kOp) { case GRPC_OP_SEND_INITIAL_METADATA: return "SendInitialMetadata"; case GRPC_OP_SEND_MESSAGE: @@ -3790,30 +3377,34 @@ class MaybeOpImpl { case GRPC_OP_RECV_STATUS_ON_CLIENT: return "RecvStatusOnClient"; } - return absl::StrCat("UnknownOp(", op, ")"); + Crash("Unreachable"); } - static State MoveState(State& state) { - if (absl::holds_alternative(state)) return Dismissed{}; - // Can't move after first poll => Promise is not an option - return std::move(absl::get(state)); - } + // gcc-12 has problems with this being a variant + GPR_NO_UNIQUE_ADDRESS State state_; + union { + PromiseFactory promise_factory_; + Promise promise_; + }; }; -// MaybeOp captures a fairly complicated dance we need to do for the batch API. -// We first check if an op is included or not, and if it is, we run the setup -// function in the context of the API call (NOT in the call party). -// This setup function returns a promise factory which we'll then run *in* the +// MaybeOp captures a fairly complicated dance we need to do for the batch +// API. We first check if an op is included or not, and if it is, we run the +// setup function in the context of the API call (NOT in the call party). This +// setup function returns a promise factory which we'll then run *in* the // party to do initial setup, and have it return the promise that we'll // ultimately poll on til completion. // Once we express our surface API in terms of core internal types this whole // dance will go away. -template -auto MaybeOp(const grpc_op* ops, uint8_t idx, SetupFn setup) { - if (idx == 255) { - return MaybeOpImpl(); +template +auto MaybeOp(const grpc_op* ops, const std::array& idxs, + SetupFn setup) { + using SetupResult = decltype(std::declval()(grpc_op())); + if (idxs[op_type] == 255) { + return MaybeOpImpl(); } else { - return MaybeOpImpl(setup(ops[idx]), ops[idx].op); + auto r = setup(ops[idxs[op_type]]); + return MaybeOpImpl(std::move(r)); } } @@ -3851,63 +3442,61 @@ PollBatchLogger LogPollBatch(void* tag, F f) { } } // namespace -StatusFlag ServerCallSpine::FinishRecvMessage( - NextResult result) { - if (result.has_value()) { - MessageHandle& message = *result; - NoteLastMessageFlags(message->flags()); - if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) && - (incoming_compression_algorithm() != GRPC_COMPRESS_NONE)) { - *recv_message_ = grpc_raw_compressed_byte_buffer_create( - nullptr, 0, incoming_compression_algorithm()); - } else { - *recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0); - } - grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(), - &(*recv_message_)->data.raw.slice_buffer); +StatusFlag ServerCall::FinishRecvMessage( + ValueOrFailure> result) { + if (!result.ok()) { if (grpc_call_trace.enabled()) { gpr_log(GPR_INFO, "%s[call] RecvMessage: outstanding_recv " - "finishes: received %" PRIdPTR " byte message", - DebugTag().c_str(), - (*recv_message_)->data.raw.slice_buffer.length); + "finishes: received end-of-stream with error", + DebugTag().c_str()); } + *recv_message_ = nullptr; recv_message_ = nullptr; - return Success{}; + return Failure{}; } - if (result.cancelled()) { + if (!result->has_value()) { if (grpc_call_trace.enabled()) { gpr_log(GPR_INFO, "%s[call] RecvMessage: outstanding_recv " - "finishes: received end-of-stream with error", + "finishes: received end-of-stream", DebugTag().c_str()); } *recv_message_ = nullptr; recv_message_ = nullptr; - return Failure{}; + return Success{}; } + MessageHandle& message = **result; + NoteLastMessageFlags(message->flags()); + if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) && + (incoming_compression_algorithm() != GRPC_COMPRESS_NONE)) { + *recv_message_ = grpc_raw_compressed_byte_buffer_create( + nullptr, 0, incoming_compression_algorithm()); + } else { + *recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0); + } + grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(), + &(*recv_message_)->data.raw.slice_buffer); if (grpc_call_trace.enabled()) { gpr_log(GPR_INFO, "%s[call] RecvMessage: outstanding_recv " - "finishes: received end-of-stream", - DebugTag().c_str()); + "finishes: received %" PRIdPTR " byte message", + DebugTag().c_str(), (*recv_message_)->data.raw.slice_buffer.length); } - *recv_message_ = nullptr; recv_message_ = nullptr; return Success{}; } -void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, - void* notify_tag, - bool is_notify_tag_closure) { +void ServerCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag, + bool is_notify_tag_closure) { std::array got_ops{255, 255, 255, 255, 255, 255, 255, 255}; for (size_t op_idx = 0; op_idx < nops; op_idx++) { const grpc_op& op = ops[op_idx]; got_ops[op.op] = op_idx; } - if (!is_notify_tag_closure) grpc_cq_begin_op(cq(), notify_tag); - auto send_initial_metadata = MaybeOp( - ops, got_ops[GRPC_OP_SEND_INITIAL_METADATA], [this](const grpc_op& op) { + if (!is_notify_tag_closure) grpc_cq_begin_op(cq_, notify_tag); + auto send_initial_metadata = MaybeOp( + ops, got_ops, [this](const grpc_op& op) { auto metadata = arena()->MakePooled(); PrepareOutgoingInitialMetadata(op, *metadata); CToMetadata(op.data.send_initial_metadata.metadata, @@ -3917,27 +3506,22 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, DebugTag().c_str()); } return [this, metadata = std::move(metadata)]() mutable { - return Map(server_initial_metadata_.sender.Push(std::move(metadata)), - [this](bool r) { - server_initial_metadata_.sender.Close(); - return StatusFlag(r); - }); + return call_handler_.PushServerInitialMetadata(std::move(metadata)); }; }); auto send_message = - MaybeOp(ops, got_ops[GRPC_OP_SEND_MESSAGE], [this](const grpc_op& op) { + MaybeOp(ops, got_ops, [this](const grpc_op& op) { SliceBuffer send; grpc_slice_buffer_swap( &op.data.send_message.send_message->data.raw.slice_buffer, send.c_slice_buffer()); auto msg = arena()->MakePooled(std::move(send), op.flags); return [this, msg = std::move(msg)]() mutable { - return Map(server_to_client_messages_.sender.Push(std::move(msg)), - [](bool r) { return StatusFlag(r); }); + return call_handler_.PushMessage(std::move(msg)); }; }); - auto send_trailing_metadata = MaybeOp( - ops, got_ops[GRPC_OP_SEND_STATUS_FROM_SERVER], [this](const grpc_op& op) { + auto send_trailing_metadata = MaybeOp( + ops, got_ops, [this](const grpc_op& op) { auto metadata = arena()->MakePooled(); CToMetadata(op.data.send_status_from_server.trailing_metadata, op.data.send_status_from_server.trailing_metadata_count, @@ -3958,18 +3542,18 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, return [this, metadata = std::move(metadata)]() mutable -> Poll { CHECK(metadata != nullptr); - PushServerTrailingMetadata(std::move(metadata)); + call_handler_.PushServerTrailingMetadata(std::move(metadata)); return Success{}; }; }; }); auto recv_message = - MaybeOp(ops, got_ops[GRPC_OP_RECV_MESSAGE], [this](const grpc_op& op) { + MaybeOp(ops, got_ops, [this](const grpc_op& op) { CHECK_EQ(recv_message_, nullptr); recv_message_ = op.data.recv_message.recv_message; return [this]() mutable { - return Map(client_to_server_messages_.receiver.Next(), - [this](NextResult msg) { + return Map(call_handler_.PullMessage(), + [this](ValueOrFailure> msg) { return FinishRecvMessage(std::move(msg)); }); }; @@ -3980,10 +3564,10 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, std::move(send_trailing_metadata)), std::move(recv_message)); if (got_ops[GRPC_OP_RECV_CLOSE_ON_SERVER] != 255) { - auto recv_trailing_metadata = MaybeOp( - ops, got_ops[GRPC_OP_RECV_CLOSE_ON_SERVER], [this](const grpc_op& op) { + auto recv_trailing_metadata = MaybeOp( + ops, got_ops, [this](const grpc_op& op) { return [this, cancelled = op.data.recv_close_on_server.cancelled]() { - return Map(WasCancelled(), + return Map(call_handler_.WasCancelled(), [cancelled, this](bool result) -> Success { ResetDeadline(); *cancelled = result ? 1 : 0; @@ -3991,7 +3575,7 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, }); }; }); - SpawnInfallible( + call_handler_.SpawnInfallible( "final-batch", [primary_ops = std::move(primary_ops), recv_trailing_metadata = std::move(recv_trailing_metadata), @@ -4001,37 +3585,38 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, Seq(std::move(primary_ops), std::move(recv_trailing_metadata), [is_notify_tag_closure, notify_tag, this](StatusFlag) { return WaitForCqEndOp(is_notify_tag_closure, notify_tag, - absl::OkStatus(), cq()); + absl::OkStatus(), cq_); })); }); } else { - SpawnInfallible("batch", [primary_ops = std::move(primary_ops), - is_notify_tag_closure, notify_tag, - this]() mutable { - return LogPollBatch( - notify_tag, - Seq(std::move(primary_ops), - [is_notify_tag_closure, notify_tag, this](StatusFlag r) { + call_handler_.SpawnInfallible( + "batch", [primary_ops = std::move(primary_ops), is_notify_tag_closure, + notify_tag, this]() mutable { + return LogPollBatch( + notify_tag, + Seq(std::move(primary_ops), [is_notify_tag_closure, notify_tag, + this](StatusFlag r) { return WaitForCqEndOp(is_notify_tag_closure, notify_tag, - StatusCast(r), cq()); + StatusCast(r), cq_); })); - }); + }); } } -RefCountedPtr MakeServerCall( - ClientMetadataHandle client_initial_metadata, ServerInterface* server, - Channel* channel, Arena* arena) { - return RefCountedPtr(arena->New( - std::move(client_initial_metadata), server, channel, arena)); +grpc_call* MakeServerCall(CallHandler call_handler, + ClientMetadataHandle client_initial_metadata, + ServerInterface* server, grpc_completion_queue* cq, + grpc_metadata_array* publish_initial_metadata) { + PublishMetadataArray(client_initial_metadata.get(), publish_initial_metadata, + false); + // TODO(ctiller): ideally we'd put this in the arena with the CallHandler, + // but there's an ownership problem: CallHandler owns the arena, and so would + // get destroyed before the base class Call destructor runs, leading to + // UB/crash. Investigate another path. + return (new ServerCall(std::move(client_initial_metadata), + std::move(call_handler), server, cq)) + ->c_ptr(); } -#else -RefCountedPtr MakeServerCall(ClientMetadataHandle, - ServerInterface*, Channel*, - Arena*) { - Crash("not implemented"); -} -#endif } // namespace grpc_core diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 9fb12f279e4..9388c142f67 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -82,7 +82,7 @@ class Call : public CppImplOf, public grpc_event_engine::experimental::EventEngine:: Closure /* for deadlines */ { public: - Arena* arena() { return arena_; } + virtual Arena* arena() = 0; bool is_client() const { return is_client_; } virtual void ContextSet(grpc_context_index elem, void* value, @@ -92,7 +92,7 @@ class Call : public CppImplOf, void CancelWithStatus(grpc_status_code status, const char* description); virtual void CancelWithError(grpc_error_handle error) = 0; virtual void SetCompletionQueue(grpc_completion_queue* cq) = 0; - char* GetPeer(); + virtual char* GetPeer() = 0; virtual grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag, bool is_notify_tag_closure) = 0; @@ -157,25 +157,15 @@ class Call : public CppImplOf, Call* sibling_prev = nullptr; }; - Call(Arena* arena, bool is_client, Timestamp send_deadline, - RefCountedPtr channel) - : channel_(std::move(channel)), - arena_(arena), - send_deadline_(send_deadline), - is_client_(is_client) { - DCHECK_NE(arena_, nullptr); - DCHECK(channel_ != nullptr); - } + Call(bool is_client, Timestamp send_deadline, + grpc_event_engine::experimental::EventEngine* event_engine) + : send_deadline_(send_deadline), + is_client_(is_client), + event_engine_(event_engine) {} ~Call() override = default; - void DeleteThis(); - ParentCall* GetOrCreateParentCall(); ParentCall* parent_call(); - Channel* channel() const { - DCHECK(channel_ != nullptr); - return channel_.get(); - } absl::Status InitParent(Call* parent, uint32_t propagation_mask); void PublishToParent(Call* parent); @@ -221,9 +211,9 @@ class Call : public CppImplOf, gpr_cycle_counter start_time() const { return start_time_; } + virtual grpc_compression_options compression_options() = 0; + private: - RefCountedPtr channel_; - Arena* const arena_; std::atomic parent_call_{nullptr}; ChildCall* child_ = nullptr; Timestamp send_deadline_; @@ -247,34 +237,13 @@ class Call : public CppImplOf, Timestamp deadline_ ABSL_GUARDED_BY(deadline_mu_) = Timestamp::InfFuture(); grpc_event_engine::experimental::EventEngine::TaskHandle ABSL_GUARDED_BY( deadline_mu_) deadline_task_; + grpc_event_engine::experimental::EventEngine* const event_engine_; gpr_cycle_counter start_time_ = gpr_get_cycle_counter(); }; class BasicPromiseBasedCall; class ServerPromiseBasedCall; -class ServerCallContext { - public: - virtual void PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) = 0; - - // Construct the top of the server call promise for the v2 filter stack. - // TODO(ctiller): delete when v3 is available. - virtual ArenaPromise MakeTopOfServerCallPromise( - CallArgs call_args, grpc_completion_queue* cq, - absl::FunctionRef publish) = 0; - - // Server stream data as supplied by the transport (so we can link the - // transport stream up with the call again). - // TODO(ctiller): legacy API - once we move transports to promises we'll - // create the promise directly and not need to pass around this token. - virtual const void* server_stream_data() = 0; - - protected: - ~ServerCallContext() = default; -}; - // TODO(ctiller): move more call things into this type class CallContext { public: @@ -300,8 +269,6 @@ class CallContext { gpr_atm* peer_string_atm_ptr(); gpr_cycle_counter call_start_time() { return start_time_; } - ServerCallContext* server_call_context(); - void set_traced(bool traced) { traced_ = traced; } bool traced() const { return traced_; } @@ -329,9 +296,10 @@ template <> struct ContextType {}; // TODO(ctiller): remove once call-v3 finalized -RefCountedPtr MakeServerCall( - ClientMetadataHandle client_initial_metadata, ServerInterface* server, - Channel* channel, Arena* arena); +grpc_call* MakeServerCall(CallHandler call_handler, + ClientMetadataHandle client_initial_metadata, + ServerInterface* server, grpc_completion_queue* cq, + grpc_metadata_array* publish_initial_metadata); } // namespace grpc_core diff --git a/src/core/lib/surface/channel_init.cc b/src/core/lib/surface/channel_init.cc index b94b189ffea..698a57b195d 100644 --- a/src/core/lib/surface/channel_init.cc +++ b/src/core/lib/surface/channel_init.cc @@ -104,9 +104,9 @@ ChannelInit::FilterRegistration::ExcludeFromMinimalStack() { ChannelInit::FilterRegistration& ChannelInit::Builder::RegisterFilter( grpc_channel_stack_type type, const grpc_channel_filter* filter, - const ChannelFilterVtable* vtable, SourceLocation registration_source) { + FilterAdder filter_adder, SourceLocation registration_source) { filters_[type].emplace_back(std::make_unique( - filter, vtable, registration_source)); + filter, filter_adder, registration_source)); return *filters_[type].back(); } @@ -223,9 +223,10 @@ ChannelInit::StackConfig ChannelInit::BuildStackConfig( while (!dependencies.empty()) { auto filter = take_ready_dependency(); auto* registration = filter_to_registration[filter]; - filters.emplace_back( - filter, registration->vtable_, std::move(registration->predicates_), - registration->skip_v3_, registration->registration_source_); + filters.emplace_back(filter, registration->filter_adder_, + std::move(registration->predicates_), + registration->skip_v3_, + registration->registration_source_); for (auto& p : dependencies) { p.second.erase(filter); } @@ -406,78 +407,21 @@ bool ChannelInit::CreateStack(ChannelStackBuilder* builder) const { return true; } -absl::StatusOr ChannelInit::CreateStackSegment( - grpc_channel_stack_type type, const ChannelArgs& args) const { +void ChannelInit::AddToInterceptionChainBuilder( + grpc_channel_stack_type type, InterceptionChainBuilder& builder) const { const auto& stack_config = stack_configs_[type]; - std::vector filters; - size_t channel_data_size = 0; - size_t channel_data_alignment = 0; // Based on predicates build a list of filters to include in this segment. for (const auto& filter : stack_config.filters) { if (filter.skip_v3) continue; - if (!filter.CheckPredicates(args)) continue; - if (filter.vtable == nullptr) { - return absl::InvalidArgumentError( + if (!filter.CheckPredicates(builder.channel_args())) continue; + if (filter.filter_adder == nullptr) { + builder.Fail(absl::InvalidArgumentError( absl::StrCat("Filter ", NameFromChannelFilter(filter.filter), - " has no v3-callstack vtable")); + " has no v3-callstack vtable"))); + return; } - channel_data_alignment = - std::max(channel_data_alignment, filter.vtable->alignment); - if (channel_data_size % filter.vtable->alignment != 0) { - channel_data_size += filter.vtable->alignment - - (channel_data_size % filter.vtable->alignment); - } - filters.push_back({channel_data_size, filter.vtable}); - channel_data_size += filter.vtable->size; - } - // Shortcut for empty segments. - if (filters.empty()) return StackSegment(); - // Allocate memory for the channel data, initialize channel filters into it. - uint8_t* p = static_cast( - gpr_malloc_aligned(channel_data_size, channel_data_alignment)); - for (size_t i = 0; i < filters.size(); i++) { - auto r = filters[i].vtable->init(p + filters[i].offset, args); - if (!r.ok()) { - for (size_t j = 0; j < i; j++) { - filters[j].vtable->destroy(p + filters[j].offset); - } - gpr_free_aligned(p); - return r; - } - } - return StackSegment(std::move(filters), p); -} - -/////////////////////////////////////////////////////////////////////////////// -// ChannelInit::StackSegment - -ChannelInit::StackSegment::StackSegment(std::vector filters, - uint8_t* channel_data) - : data_(MakeRefCounted(std::move(filters), channel_data)) {} - -void ChannelInit::StackSegment::AddToCallFilterStack( - CallFilters::StackBuilder& builder) { - if (data_ == nullptr) return; - data_->AddToCallFilterStack(builder); - builder.AddOwnedObject(data_); -}; - -ChannelInit::StackSegment::ChannelData::ChannelData( - std::vector filters, uint8_t* channel_data) - : filters_(std::move(filters)), channel_data_(channel_data) {} - -void ChannelInit::StackSegment::ChannelData::AddToCallFilterStack( - CallFilters::StackBuilder& builder) { - for (const auto& filter : filters_) { - filter.vtable->add_to_stack_builder(channel_data_ + filter.offset, builder); - } -} - -ChannelInit::StackSegment::ChannelData::~ChannelData() { - for (const auto& filter : filters_) { - filter.vtable->destroy(channel_data_ + filter.offset); + filter.filter_adder(builder); } - gpr_free_aligned(channel_data_); } } // namespace grpc_core diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index fcfef582994..c5067394014 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -38,6 +38,7 @@ #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/surface/channel_stack_type.h" #include "src/core/lib/transport/call_filters.h" +#include "src/core/lib/transport/interception_chain.h" /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. @@ -68,6 +69,8 @@ class ChannelInit { using InclusionPredicate = absl::AnyInvocable; // Post processor for the channel stack - applied in PostProcessorSlot order using PostProcessor = absl::AnyInvocable; + // Function that can be called to add a filter to a stack builder + using FilterAdder = void (*)(InterceptionChainBuilder&); // Post processing slots - up to one PostProcessor per slot can be registered // They run after filters registered are added to the channel stack builder, // but before Build is called - allowing ad-hoc mutation to the channel stack. @@ -77,25 +80,15 @@ class ChannelInit { kCount }; - // Vtable-like data structure for channel data initialization - struct ChannelFilterVtable { - size_t size; - size_t alignment; - absl::Status (*init)(void* data, const ChannelArgs& args); - void (*destroy)(void* data); - void (*add_to_stack_builder)(void* data, - CallFilters::StackBuilder& builder); - }; - class FilterRegistration { public: // TODO(ctiller): Remove grpc_channel_filter* arg when that can be // deprecated (once filter stack is removed). explicit FilterRegistration(const grpc_channel_filter* filter, - const ChannelFilterVtable* vtable, + FilterAdder filter_adder, SourceLocation registration_source) : filter_(filter), - vtable_(vtable), + filter_adder_(filter_adder), registration_source_(registration_source) {} FilterRegistration(const FilterRegistration&) = delete; FilterRegistration& operator=(const FilterRegistration&) = delete; @@ -170,7 +163,7 @@ class ChannelInit { private: friend class ChannelInit; const grpc_channel_filter* const filter_; - const ChannelFilterVtable* const vtable_; + const FilterAdder filter_adder_; std::vector after_; std::vector before_; std::vector predicates_; @@ -188,16 +181,17 @@ class ChannelInit { // properties of the filter being registered. // TODO(ctiller): remove in favor of the version that does not mention // grpc_channel_filter - FilterRegistration& RegisterFilter( - grpc_channel_stack_type type, const grpc_channel_filter* filter, - const ChannelFilterVtable* vtable = nullptr, - SourceLocation registration_source = {}); + FilterRegistration& RegisterFilter(grpc_channel_stack_type type, + const grpc_channel_filter* filter, + FilterAdder filter_adder = nullptr, + SourceLocation registration_source = {}); template FilterRegistration& RegisterFilter( grpc_channel_stack_type type, SourceLocation registration_source = {}) { - return RegisterFilter(type, &Filter::kFilter, - VtableForType::vtable(), - registration_source); + return RegisterFilter( + type, &Filter::kFilter, + [](InterceptionChainBuilder& builder) { builder.Add(); }, + registration_source); } // Filter does not participate in v3 @@ -232,58 +226,13 @@ class ChannelInit { [static_cast(PostProcessorSlot::kCount)]; }; - // A set of channel filters that can be added to a call stack. - // TODO(ctiller): move this out so it can be used independently of - // the global registration mechanisms. - class StackSegment final { - public: - // Registration of one channel filter in the stack. - struct ChannelFilter { - size_t offset; - const ChannelFilterVtable* vtable; - }; - - StackSegment() = default; - explicit StackSegment(std::vector filters, - uint8_t* channel_data); - StackSegment(const StackSegment& other) = delete; - StackSegment& operator=(const StackSegment& other) = delete; - StackSegment(StackSegment&& other) noexcept = default; - StackSegment& operator=(StackSegment&& other) = default; - - // Add this segment to a call filter stack builder - void AddToCallFilterStack(CallFilters::StackBuilder& builder); - - private: - // Combined channel data for the stack - class ChannelData : public RefCounted { - public: - explicit ChannelData(std::vector filters, - uint8_t* channel_data); - ~ChannelData() override; - - void AddToCallFilterStack(CallFilters::StackBuilder& builder); - - private: - std::vector filters_; - uint8_t* channel_data_; - }; - - RefCountedPtr data_; - }; - /// Construct a channel stack of some sort: see channel_stack.h for details /// \a builder is the channel stack builder to build into. GRPC_MUST_USE_RESULT bool CreateStack(ChannelStackBuilder* builder) const; - // Create a segment of a channel stack. - // Terminators and post processors are not included in this construction: - // terminators are a legacy filter-stack concept, and post processors - // need to migrate to other mechanisms. - // TODO(ctiller): figure out other mechanisms. - absl::StatusOr CreateStackSegment( - grpc_channel_stack_type type, const ChannelArgs& args) const; + void AddToInterceptionChainBuilder(grpc_channel_stack_type type, + InterceptionChainBuilder& builder) const; private: // The type of object returned by a filter's Create method. @@ -292,16 +241,16 @@ class ChannelInit { typename decltype(T::Create(ChannelArgs(), {}))::value_type; struct Filter { - Filter(const grpc_channel_filter* filter, const ChannelFilterVtable* vtable, + Filter(const grpc_channel_filter* filter, FilterAdder filter_adder, std::vector predicates, bool skip_v3, SourceLocation registration_source) : filter(filter), - vtable(vtable), + filter_adder(filter_adder), predicates(std::move(predicates)), registration_source(registration_source), skip_v3(skip_v3) {} const grpc_channel_filter* filter; - const ChannelFilterVtable* vtable; + const FilterAdder filter_adder; std::vector predicates; SourceLocation registration_source; bool skip_v3 = false; @@ -313,17 +262,6 @@ class ChannelInit { std::vector post_processors; }; - template - struct VtableForType { - static const ChannelFilterVtable* vtable() { return nullptr; } - }; - - template - struct VtableForType> { - static const ChannelFilterVtable kVtable; - static const ChannelFilterVtable* vtable() { return &kVtable; } - }; - StackConfig stack_configs_[GRPC_NUM_CHANNEL_STACK_TYPES]; static StackConfig BuildStackConfig( @@ -331,22 +269,6 @@ class ChannelInit { PostProcessor* post_processors, grpc_channel_stack_type type); }; -template -const ChannelInit::ChannelFilterVtable - ChannelInit::VtableForType>::kVtable = { - sizeof(CreatedType), alignof(CreatedType), - [](void* data, const ChannelArgs& args) -> absl::Status { - // TODO(ctiller): fill in ChannelFilter::Args (2nd arg) - absl::StatusOr> r = T::Create(args, {}); - if (!r.ok()) return r.status(); - new (data) CreatedType(std::move(*r)); - return absl::OkStatus(); - }, - [](void* data) { Destruct(static_cast*>(data)); }, - [](void* data, CallFilters::StackBuilder& builder) { - builder.Add(static_cast*>(data)->get()); - }}; - } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_SURFACE_CHANNEL_INIT_H diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 3ff4c77f062..b2a766ac8a0 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -66,10 +66,10 @@ static bool g_shutting_down ABSL_GUARDED_BY(g_init_mu) = false; namespace grpc_core { void RegisterSecurityFilters(CoreConfiguration::Builder* builder) { builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_SUBCHANNEL) .IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_DIRECT_CHANNEL) .IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR); builder->channel_init() ->RegisterFilter(GRPC_SERVER_CHANNEL) diff --git a/src/core/lib/transport/call_destination.h b/src/core/lib/transport/call_destination.h index 77683e230f5..938e0fd3725 100644 --- a/src/core/lib/transport/call_destination.h +++ b/src/core/lib/transport/call_destination.h @@ -51,6 +51,24 @@ class CallDestination : public DualRefCounted { virtual void HandleCall(CallHandler unstarted_call_handler) = 0; }; +template +auto MakeCallDestinationFromHandlerFunction(HC handle_call) { + class Impl : public CallDestination { + public: + explicit Impl(HC handle_call) : handle_call_(std::move(handle_call)) {} + + void Orphaned() override {} + + void HandleCall(CallHandler call_handler) override { + handle_call_(std::move(call_handler)); + } + + private: + HC handle_call_; + }; + return MakeRefCounted(std::move(handle_call)); +} + } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_DESTINATION_H diff --git a/src/core/lib/transport/call_filters.h b/src/core/lib/transport/call_filters.h index a9e3a1c5b98..d637b6fb0de 100644 --- a/src/core/lib/transport/call_filters.h +++ b/src/core/lib/transport/call_filters.h @@ -1245,6 +1245,42 @@ const NoInterceptor template const NoInterceptor ServerTrailingMetadataInterceptor::Call::OnFinalize; +template +class ClientInitialMetadataInterceptor { + public: + class Call { + public: + auto OnClientInitialMetadata(ClientMetadata& md, + ClientInitialMetadataInterceptor* filter) { + return filter->fn_(md); + } + static const NoInterceptor OnServerInitialMetadata; + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + static const NoInterceptor OnServerTrailingMetadata; + static const NoInterceptor OnFinalize; + }; + + explicit ClientInitialMetadataInterceptor(Fn fn) : fn_(std::move(fn)) {} + + private: + GPR_NO_UNIQUE_ADDRESS Fn fn_; +}; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnServerInitialMetadata; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnClientToServerMessage; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnServerToClientMessage; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnServerTrailingMetadata; +template +const NoInterceptor ClientInitialMetadataInterceptor::Call::OnFinalize; + } // namespace filters_detail // Execution environment for a stack of filters. @@ -1302,6 +1338,14 @@ class CallFilters { AddOwnedObject([](void* p) { delete static_cast(p); }, p.release()); } + template + void AddOnClientInitialMetadata(Fn fn) { + auto filter = std::make_unique< + filters_detail::ClientInitialMetadataInterceptor>(std::move(fn)); + Add(filter.get()); + AddOwnedObject(std::move(filter)); + } + template void AddOnServerTrailingMetadata(Fn fn) { auto filter = std::make_unique< diff --git a/src/core/lib/transport/call_spine.h b/src/core/lib/transport/call_spine.h index 8593e47e9c8..59c1fc2da16 100644 --- a/src/core/lib/transport/call_spine.h +++ b/src/core/lib/transport/call_spine.h @@ -518,6 +518,8 @@ class CallHandler { auto PullMessage() { return spine_->PullClientToServerMessage(); } + auto WasCancelled() { return spine_->WasCancelled(); } + template void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory, DebugLocation whence = {}) { @@ -536,11 +538,15 @@ class CallHandler { Arena* arena() { return spine_->arena(); } - grpc_event_engine::experimental::EventEngine* event_engine() { + grpc_event_engine::experimental::EventEngine* event_engine() const { return DownCast(spine_.get())->event_engine(); } // TODO(ctiller): re-evaluate this API + const grpc_call_context_element* legacy_context() const { + return DownCast(spine_.get())->legacy_context(); + } + grpc_call_context_element* legacy_context() { return DownCast(spine_.get())->legacy_context(); } diff --git a/src/core/lib/transport/interception_chain.h b/src/core/lib/transport/interception_chain.h index 5b05e481ff6..e9dcb937b19 100644 --- a/src/core/lib/transport/interception_chain.h +++ b/src/core/lib/transport/interception_chain.h @@ -175,12 +175,23 @@ class InterceptionChainBuilder final { return *this; }; + // Add a filter that just mutates client initial metadata. + template + void AddOnClientInitialMetadata(F f) { + stack_builder().AddOnClientInitialMetadata(std::move(f)); + } + // Add a filter that just mutates server trailing metadata. template void AddOnServerTrailingMetadata(F f) { stack_builder().AddOnServerTrailingMetadata(std::move(f)); } + void Fail(absl::Status status) { + CHECK(!status.ok()) << status; + if (status_.ok()) status_ = std::move(status); + } + // Build this stack absl::StatusOr> Build( FinalDestination final_destination); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 65f57fdd475..5dbe2c6695f 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -55,6 +55,7 @@ #include "src/core/lib/promise/pipe.h" #include "src/core/lib/resource_quota/arena.h" #include "src/core/lib/slice/slice_buffer.h" +#include "src/core/lib/transport/call_destination.h" #include "src/core/lib/transport/call_final_info.h" #include "src/core/lib/transport/call_spine.h" #include "src/core/lib/transport/connectivity_state.h" @@ -481,6 +482,15 @@ typedef struct grpc_transport_op { grpc_handler_private_op_data handler_private; } grpc_transport_op; +// Allocate a grpc_transport_op, and preconfigure the on_complete closure to +// \a on_complete and then delete the returned transport op +grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete); +// Allocate a grpc_transport_stream_op_batch, and preconfigure the on_complete +// closure +// to \a on_complete and then delete the returned transport op +grpc_transport_stream_op_batch* grpc_make_transport_stream_op( + grpc_closure* on_complete); + void grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch* batch, grpc_error_handle error, grpc_core::CallCombiner* call_combiner); @@ -507,6 +517,21 @@ class Transport : public InternallyRefCounted { struct RawPointerChannelArgTag {}; static absl::string_view ChannelArgName() { return GRPC_ARG_TRANSPORT; } + // Though internally ref counted transports expose their "Ref" method to + // create a RefCountedPtr to themselves. The OrphanablePtr owner is the + // singleton decision maker on whether the transport should be destroyed or + // not. + // TODO(ctiller): consider moving to a DualRefCounted model (with the + // disadvantage that we would accidentally have many strong owners which is + // unnecessary for this type). + RefCountedPtr Ref() { + return InternallyRefCounted::Ref(); + } + template + RefCountedPtr RefAsSubclass() { + return InternallyRefCounted::RefAsSubclass(); + } + virtual FilterStackTransport* filter_stack_transport() = 0; virtual ClientTransport* client_transport() = 0; virtual ServerTransport* server_transport() = 0; @@ -527,6 +552,20 @@ class Transport : public InternallyRefCounted { // implementation of grpc_transport_perform_op virtual void PerformOp(grpc_transport_op* op) = 0; + void StartConnectivityWatch( + OrphanablePtr watcher) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->start_connectivity_watch = std::move(watcher); + PerformOp(op); + } + + void DisconnectWithError(grpc_error_handle error) { + CHECK(!error.ok()) << error; + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->disconnect_with_error = error; + PerformOp(op); + } + // implementation of grpc_transport_get_endpoint virtual grpc_endpoint* GetEndpoint() = 0; }; @@ -582,24 +621,9 @@ class ClientTransport : public Transport { class ServerTransport : public Transport { public: - // Acceptor helps transports create calls. - class Acceptor { - public: - // Returns an arena that can be used to allocate memory for initial metadata - // parsing, and later passed to CreateCall() as the underlying arena for - // that call. - virtual Arena* CreateArena() = 0; - // Create a call at the server (or fail) - // arena must have been previously allocated by CreateArena() - virtual absl::StatusOr CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) = 0; - - protected: - ~Acceptor() = default; - }; - // Called once slightly after transport setup to register the accept function. - virtual void SetAcceptor(Acceptor* acceptor) = 0; + virtual void SetCallDestination( + RefCountedPtr unstarted_call_handler) = 0; protected: ~ServerTransport() override = default; @@ -607,15 +631,6 @@ class ServerTransport : public Transport { } // namespace grpc_core -// Allocate a grpc_transport_op, and preconfigure the on_complete closure to -// \a on_complete and then delete the returned transport op -grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete); -// Allocate a grpc_transport_stream_op_batch, and preconfigure the on_complete -// closure -// to \a on_complete and then delete the returned transport op -grpc_transport_stream_op_batch* grpc_make_transport_stream_op( - grpc_closure* on_complete); - namespace grpc_core { // This is the key to be used for loading/storing keepalive_throttling in the // absl::Status object. diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc index c0205fa8497..80b4010593e 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_plugin_registry.cc @@ -79,10 +79,11 @@ namespace { void RegisterBuiltins(CoreConfiguration::Builder* builder) { RegisterServerCallTracerFilter(builder); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_LAME_CHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_LAME_CHANNEL) .Terminal(); builder->channel_init() ->RegisterFilter(GRPC_SERVER_CHANNEL, &Server::kServerTopFilter) + .SkipV3() .BeforeAll(); } diff --git a/src/core/server/server.cc b/src/core/server/server.cc index 04d0f52da3e..40c87eda174 100644 --- a/src/core/server/server.cc +++ b/src/core/server/server.cc @@ -57,6 +57,7 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/mpscq.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/status_helper.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/pollset_set.h" @@ -81,6 +82,7 @@ #include "src/core/lib/surface/wait_for_cq_end_op.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/interception_chain.h" namespace grpc_core { @@ -235,7 +237,8 @@ struct Server::RequestedCall { template void Complete(OptionalPayload payload, ClientMetadata& md) { - Timestamp deadline = GetContext()->deadline(); + Timestamp deadline = + md.get(GrpcTimeoutMetadata()).value_or(Timestamp::InfFuture()); switch (type) { case RequestedCall::Type::BATCH_CALL: CHECK(!payload.has_value()); @@ -288,23 +291,29 @@ struct Server::RequestedCall { // application to explicitly request RPCs and then matching those to incoming // RPCs, along with a slow path by which incoming RPCs are put on a locked // pending list if they aren't able to be matched to an application request. -class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { +class Server::RealRequestMatcher : public RequestMatcherInterface { public: - explicit RealRequestMatcherFilterStack(Server* server) + explicit RealRequestMatcher(Server* server) : server_(server), requests_per_cq_(server->cqs_.size()) {} - ~RealRequestMatcherFilterStack() override { + ~RealRequestMatcher() override { for (LockedMultiProducerSingleConsumerQueue& queue : requests_per_cq_) { CHECK_EQ(queue.Pop(), nullptr); } - CHECK(pending_.empty()); + CHECK(pending_filter_stack_.empty()); + CHECK(pending_promises_.empty()); } void ZombifyPending() override { - while (!pending_.empty()) { - pending_.front().calld->SetState(CallData::CallState::ZOMBIED); - pending_.front().calld->KillZombie(); - pending_.pop(); + while (!pending_filter_stack_.empty()) { + pending_filter_stack_.front().calld->SetState( + CallData::CallState::ZOMBIED); + pending_filter_stack_.front().calld->KillZombie(); + pending_filter_stack_.pop(); + } + while (!pending_promises_.empty()) { + pending_promises_.front()->Finish(absl::InternalError("Server closed")); + pending_promises_.pop(); } } @@ -329,35 +338,56 @@ class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { // matching calls struct NextPendingCall { RequestedCall* rc = nullptr; - CallData* pending; + CallData* pending_filter_stack = nullptr; + PendingCallPromises pending_promise; }; while (true) { NextPendingCall pending_call; { MutexLock lock(&server_->mu_call_); - while (!pending_.empty() && - pending_.front().Age() > server_->max_time_in_pending_queue_) { - pending_.front().calld->SetState(CallData::CallState::ZOMBIED); - pending_.front().calld->KillZombie(); - pending_.pop(); + while (!pending_filter_stack_.empty() && + pending_filter_stack_.front().Age() > + server_->max_time_in_pending_queue_) { + pending_filter_stack_.front().calld->SetState( + CallData::CallState::ZOMBIED); + pending_filter_stack_.front().calld->KillZombie(); + pending_filter_stack_.pop(); } - if (!pending_.empty()) { + if (!pending_promises_.empty()) { pending_call.rc = reinterpret_cast( requests_per_cq_[request_queue_index].Pop()); if (pending_call.rc != nullptr) { - pending_call.pending = pending_.front().calld; - pending_.pop(); + pending_call.pending_promise = + std::move(pending_promises_.front()); + pending_promises_.pop(); + } + } else if (!pending_filter_stack_.empty()) { + pending_call.rc = reinterpret_cast( + requests_per_cq_[request_queue_index].Pop()); + if (pending_call.rc != nullptr) { + pending_call.pending_filter_stack = + pending_filter_stack_.front().calld; + pending_filter_stack_.pop(); } } } if (pending_call.rc == nullptr) break; - if (!pending_call.pending->MaybeActivate()) { - // Zombied Call - pending_call.pending->KillZombie(); - requests_per_cq_[request_queue_index].Push( - &pending_call.rc->mpscq_node); + if (pending_call.pending_filter_stack != nullptr) { + if (!pending_call.pending_filter_stack->MaybeActivate()) { + // Zombied Call + pending_call.pending_filter_stack->KillZombie(); + requests_per_cq_[request_queue_index].Push( + &pending_call.rc->mpscq_node); + } else { + pending_call.pending_filter_stack->Publish(request_queue_index, + pending_call.rc); + } } else { - pending_call.pending->Publish(request_queue_index, pending_call.rc); + if (!pending_call.pending_promise->Finish( + server(), request_queue_index, pending_call.rc)) { + requests_per_cq_[request_queue_index].Push( + &pending_call.rc->mpscq_node); + } } } } @@ -395,7 +425,7 @@ class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { } if (rc == nullptr) { calld->SetState(CallData::CallState::PENDING); - pending_.push(PendingCall{calld}); + pending_filter_stack_.push(PendingCallFilterStack{calld}); return; } } @@ -403,91 +433,6 @@ class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { calld->Publish(cq_idx, rc); } - ArenaPromise> MatchRequest(size_t) override { - Crash("not implemented for filter stack request matcher"); - } - - Server* server() const final { return server_; } - - private: - Server* const server_; - struct PendingCall { - CallData* calld; - Timestamp created = Timestamp::Now(); - Duration Age() { return Timestamp::Now() - created; } - }; - std::queue pending_; - std::vector requests_per_cq_; -}; - -class Server::RealRequestMatcherPromises : public RequestMatcherInterface { - public: - explicit RealRequestMatcherPromises(Server* server) - : server_(server), requests_per_cq_(server->cqs_.size()) {} - - ~RealRequestMatcherPromises() override { - for (LockedMultiProducerSingleConsumerQueue& queue : requests_per_cq_) { - CHECK_EQ(queue.Pop(), nullptr); - } - } - - void ZombifyPending() override { - while (!pending_.empty()) { - pending_.front()->Finish(absl::InternalError("Server closed")); - pending_.pop(); - } - } - - void KillRequests(grpc_error_handle error) override { - for (size_t i = 0; i < requests_per_cq_.size(); i++) { - RequestedCall* rc; - while ((rc = reinterpret_cast( - requests_per_cq_[i].Pop())) != nullptr) { - server_->FailCall(i, rc, error); - } - } - } - - size_t request_queue_count() const override { - return requests_per_cq_.size(); - } - - void RequestCallWithPossiblePublish(size_t request_queue_index, - RequestedCall* call) override { - if (requests_per_cq_[request_queue_index].Push(&call->mpscq_node)) { - // this was the first queued request: we need to lock and start - // matching calls - struct NextPendingCall { - RequestedCall* rc = nullptr; - PendingCall pending; - }; - while (true) { - NextPendingCall pending_call; - { - MutexLock lock(&server_->mu_call_); - if (!pending_.empty()) { - pending_call.rc = reinterpret_cast( - requests_per_cq_[request_queue_index].Pop()); - if (pending_call.rc != nullptr) { - pending_call.pending = std::move(pending_.front()); - pending_.pop(); - } - } - } - if (pending_call.rc == nullptr) break; - if (!pending_call.pending->Finish(server(), request_queue_index, - pending_call.rc)) { - requests_per_cq_[request_queue_index].Push( - &pending_call.rc->mpscq_node); - } - } - } - } - - void MatchOrQueue(size_t, CallData*) override { - Crash("not implemented for promises"); - } - ArenaPromise> MatchRequest( size_t start_request_queue_index) override { for (size_t i = 0; i < requests_per_cq_.size(); i++) { @@ -509,10 +454,11 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { { std::vector> removed_pending; MutexLock lock(&server_->mu_call_); - while (!pending_.empty() && - pending_.front()->Age() > server_->max_time_in_pending_queue_) { - removed_pending.push_back(std::move(pending_.front())); - pending_.pop(); + while (!pending_promises_.empty() && + pending_promises_.front()->Age() > + server_->max_time_in_pending_queue_) { + removed_pending.push_back(std::move(pending_promises_.front())); + pending_promises_.pop(); } for (loop_count = 0; loop_count < requests_per_cq_.size(); loop_count++) { cq_idx = @@ -521,14 +467,14 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { if (rc != nullptr) break; } if (rc == nullptr) { - if (server_->pending_backlog_protector_.Reject(pending_.size(), + if (server_->pending_backlog_protector_.Reject(pending_promises_.size(), server_->bitgen_)) { return Immediate(absl::ResourceExhaustedError( "Too many pending requests for this server")); } auto w = std::make_shared( GetContext()->MakeOwningWaker()); - pending_.push(w); + pending_promises_.push(w); return OnCancel( [w]() -> Poll> { std::unique_ptr> r( @@ -546,6 +492,11 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { private: Server* const server_; + struct PendingCallFilterStack { + CallData* calld; + Timestamp created = Timestamp::Now(); + Duration Age() { return Timestamp::Now() - created; } + }; struct ActivityWaiter { using ResultType = absl::StatusOr; explicit ActivityWaiter(Waker waker) : waker(std::move(waker)) {} @@ -580,8 +531,9 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { std::atomic result{nullptr}; const Timestamp created = Timestamp::Now(); }; - using PendingCall = std::shared_ptr; - std::queue pending_; + using PendingCallPromises = std::shared_ptr; + std::queue pending_filter_stack_; + std::queue pending_promises_; std::vector requests_per_cq_; }; @@ -784,13 +736,40 @@ class ChannelBroadcaster { } // namespace +// +// Server::TransportConnectivityWatcher +// + +class Server::TransportConnectivityWatcher + : public AsyncConnectivityStateWatcherInterface { + public: + TransportConnectivityWatcher(RefCountedPtr transport, + RefCountedPtr server) + : transport_(std::move(transport)), server_(std::move(server)) {} + + private: + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& /*status*/) override { + // Don't do anything until we are being shut down. + if (new_state != GRPC_CHANNEL_SHUTDOWN) return; + // Shut down channel. + MutexLock lock(&server_->mu_global_); + server_->connections_.erase(transport_.get()); + --server_->connections_open_; + server_->MaybeFinishShutdown(); + } + + RefCountedPtr transport_; + RefCountedPtr server_; +}; + // // Server // const grpc_channel_filter Server::kServerTopFilter = { Server::CallData::StartTransportStreamOpBatch, - Server::ChannelData::MakeCallPromise, + nullptr, [](grpc_channel_element*, CallSpineInterface*) { // TODO(ctiller): remove the server filter when call-v3 is finalized }, @@ -826,12 +805,91 @@ RefCountedPtr CreateChannelzNode( return channelz_node; } +absl::StatusOr CheckClientMetadata( + ValueOrFailure md) { + if (!md.ok()) { + return absl::InternalError("Missing metadata"); + } + if (!md.value()->get_pointer(HttpPathMetadata())) { + return absl::InternalError("Missing :path header"); + } + if (!md.value()->get_pointer(HttpAuthorityMetadata())) { + return absl::InternalError("Missing :authority header"); + } + return std::move(*md); +} } // namespace +auto Server::MatchAndPublishCall(CallHandler call_handler) { + call_handler.SpawnGuarded("request_matcher", [this, call_handler]() mutable { + return TrySeq( + // Wait for initial metadata to pass through all filters + Map(call_handler.PullClientInitialMetadata(), CheckClientMetadata), + // Match request with requested call + [this, call_handler](ClientMetadataHandle md) mutable { + auto* registered_method = static_cast( + md->get(GrpcRegisteredMethod()).value_or(nullptr)); + RequestMatcherInterface* rm; + grpc_server_register_method_payload_handling payload_handling = + GRPC_SRM_PAYLOAD_NONE; + if (registered_method == nullptr) { + rm = unregistered_request_matcher_.get(); + } else { + payload_handling = registered_method->payload_handling; + rm = registered_method->matcher.get(); + } + auto maybe_read_first_message = If( + payload_handling == GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, + [call_handler]() mutable { return call_handler.PullMessage(); }, + []() -> ValueOrFailure> { + return ValueOrFailure>( + absl::nullopt); + }); + return TryJoin( + std::move(maybe_read_first_message), rm->MatchRequest(0), + [md = std::move(md)]() mutable { + return ValueOrFailure(std::move(md)); + }); + }, + // Publish call to cq + [call_handler, this](std::tuple, + RequestMatcherInterface::MatchResult, + ClientMetadataHandle> + r) { + RequestMatcherInterface::MatchResult& mr = std::get<1>(r); + auto md = std::move(std::get<2>(r)); + auto* rc = mr.TakeCall(); + rc->Complete(std::move(std::get<0>(r)), *md); + grpc_call* call = + MakeServerCall(call_handler, std::move(md), this, + rc->cq_bound_to_call, rc->initial_metadata); + *rc->call = call; + return Map(WaitForCqEndOp(false, rc->tag, absl::OkStatus(), mr.cq()), + [rc = std::unique_ptr(rc)](Empty) { + return absl::OkStatus(); + }); + }); + }); +} + +absl::StatusOr> +Server::MakeCallDestination(const ChannelArgs& args) { + InterceptionChainBuilder builder(args); + builder.AddOnClientInitialMetadata( + [this](ClientMetadata& md) { SetRegisteredMethodOnMetadata(md); }); + CoreConfiguration::Get().channel_init().AddToInterceptionChainBuilder( + GRPC_SERVER_CHANNEL, builder); + return builder.Build( + MakeCallDestinationFromHandlerFunction([this](CallHandler handler) { + return MatchAndPublishCall(std::move(handler)); + })); +} + Server::Server(const ChannelArgs& args) : channel_args_(args), channelz_node_(CreateChannelzNode(args)), server_call_tracer_factory_(ServerCallTracerFactory::Get(args)), + compression_options_(CompressionOptionsFromChannelArgs(args)), max_time_in_pending_queue_(Duration::Seconds( channel_args_ .GetInt(GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS) @@ -862,15 +920,6 @@ void Server::AddListener(OrphanablePtr listener) { } void Server::Start() { - auto make_real_request_matcher = - [this]() -> std::unique_ptr { - if (IsPromiseBasedServerCallEnabled()) { - return std::make_unique(this); - } else { - return std::make_unique(this); - } - }; - started_ = true; for (grpc_completion_queue* cq : cqs_) { if (grpc_cq_can_listen(cq)) { @@ -878,11 +927,11 @@ void Server::Start() { } } if (unregistered_request_matcher_ == nullptr) { - unregistered_request_matcher_ = make_real_request_matcher(); + unregistered_request_matcher_ = std::make_unique(this); } for (auto& rm : registered_methods_) { if (rm.second->matcher == nullptr) { - rm.second->matcher = make_real_request_matcher(); + rm.second->matcher = std::make_unique(this); } } { @@ -913,37 +962,61 @@ grpc_error_handle Server::SetupTransport( const RefCountedPtr& socket_node) { // Create channel. global_stats().IncrementServerChannelsCreated(); - absl::StatusOr> channel = - LegacyChannel::Create("", args.SetObject(transport), GRPC_SERVER_CHANNEL); - if (!channel.ok()) { - return absl_status_to_grpc_error(channel.status()); - } - ChannelData* chand = static_cast( - grpc_channel_stack_element((*channel)->channel_stack(), 0)->channel_data); - // Set up CQs. - size_t cq_idx; - for (cq_idx = 0; cq_idx < cqs_.size(); cq_idx++) { - if (grpc_cq_pollset(cqs_[cq_idx]) == accepting_pollset) break; - } - if (cq_idx == cqs_.size()) { - // Completion queue not found. Pick a random one to publish new calls to. - cq_idx = static_cast(rand()) % std::max(1, cqs_.size()); - } // Set up channelz node. - intptr_t channelz_socket_uuid = 0; - if (socket_node != nullptr) { - channelz_socket_uuid = socket_node->uuid(); - channelz_node_->AddChildSocket(socket_node); - } - // Initialize chand. - chand->InitTransport(Ref(), std::move(*channel), cq_idx, transport, - channelz_socket_uuid); + if (transport->server_transport() != nullptr) { + // Take ownership + // TODO(ctiller): post-v3-transition make this method take an + // OrphanablePtr directly. + OrphanablePtr t(transport->server_transport()); + auto destination = MakeCallDestination(args.SetObject(transport)); + if (!destination.ok()) { + return absl_status_to_grpc_error(destination.status()); + } + // TODO(ctiller): add channelz node + t->SetCallDestination(std::move(*destination)); + MutexLock lock(&mu_global_); + if (ShutdownCalled()) { + t->DisconnectWithError(GRPC_ERROR_CREATE("Server shutdown")); + } + t->StartConnectivityWatch(MakeOrphanable( + t->RefAsSubclass(), Ref())); + gpr_log(GPR_INFO, "Adding connection"); + connections_.emplace(std::move(t)); + ++connections_open_; + } else { + CHECK(transport->filter_stack_transport() != nullptr); + absl::StatusOr> channel = LegacyChannel::Create( + "", args.SetObject(transport), GRPC_SERVER_CHANNEL); + if (!channel.ok()) { + return absl_status_to_grpc_error(channel.status()); + } + ChannelData* chand = static_cast( + grpc_channel_stack_element((*channel)->channel_stack(), 0) + ->channel_data); + // Set up CQs. + size_t cq_idx; + for (cq_idx = 0; cq_idx < cqs_.size(); cq_idx++) { + if (grpc_cq_pollset(cqs_[cq_idx]) == accepting_pollset) break; + } + if (cq_idx == cqs_.size()) { + // Completion queue not found. Pick a random one to publish new calls to. + cq_idx = static_cast(rand()) % std::max(1, cqs_.size()); + } + intptr_t channelz_socket_uuid = 0; + if (socket_node != nullptr) { + channelz_socket_uuid = socket_node->uuid(); + channelz_node_->AddChildSocket(socket_node); + } + // Initialize chand. + chand->InitTransport(Ref(), std::move(*channel), cq_idx, transport, + channelz_socket_uuid); + } return absl::OkStatus(); } bool Server::HasOpenConnections() { MutexLock lock(&mu_global_); - return !channels_.empty(); + return !channels_.empty() || !connections_.empty(); } void Server::SetRegisteredMethodAllocator( @@ -1023,16 +1096,18 @@ void Server::MaybeFinishShutdown() { MutexLock lock(&mu_call_); KillPendingWorkLocked(GRPC_ERROR_CREATE("Server Shutdown")); } - if (!channels_.empty() || listeners_destroyed_ < listeners_.size()) { + if (!channels_.empty() || connections_open_ > 0 || + listeners_destroyed_ < listeners_.size()) { if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_shutdown_message_time_), gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { last_shutdown_message_time_ = gpr_now(GPR_CLOCK_REALTIME); gpr_log(GPR_DEBUG, - "Waiting for %" PRIuPTR " channels and %" PRIuPTR "/%" PRIuPTR + "Waiting for %" PRIuPTR " channels %" PRIuPTR + " connections and %" PRIuPTR "/%" PRIuPTR " listeners to be destroyed before shutting down server", - channels_.size(), listeners_.size() - listeners_destroyed_, - listeners_.size()); + channels_.size(), connections_open_, + listeners_.size() - listeners_destroyed_, listeners_.size()); } return; } @@ -1095,6 +1170,7 @@ void DonePublishedShutdown(void* /*done_arg*/, grpc_cq_completion* storage) { // -- Once there are no more calls in progress, the channel is closed. void Server::ShutdownAndNotify(grpc_completion_queue* cq, void* tag) { ChannelBroadcaster broadcaster; + absl::flat_hash_set> removing_connections; { // Wait for startup to be finished. Locks mu_global. MutexLock lock(&mu_global_); @@ -1114,6 +1190,7 @@ void Server::ShutdownAndNotify(grpc_completion_queue* cq, void* tag) { } last_shutdown_message_time_ = gpr_now(GPR_CLOCK_REALTIME); broadcaster.FillChannelsLocked(GetChannelsLocked()); + removing_connections.swap(connections_); // Collect all unregistered then registered calls. { MutexLock lock(&mu_call_); @@ -1300,17 +1377,6 @@ Server::ChannelData::~ChannelData() { } } -Arena* Server::ChannelData::CreateArena() { return channel_->CreateArena(); } - -absl::StatusOr Server::ChannelData::CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) { - SetRegisteredMethodOnMetadata(*client_initial_metadata); - auto call = MakeServerCall(std::move(client_initial_metadata), server_.get(), - channel_.get(), arena); - InitCall(call); - return CallInitiator(std::move(call)); -} - void Server::ChannelData::InitTransport(RefCountedPtr server, OrphanablePtr channel, size_t cq_idx, Transport* transport, @@ -1327,22 +1393,15 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, } // Start accept_stream transport op. grpc_transport_op* op = grpc_make_transport_op(nullptr); - int accept_stream_types = 0; - if (transport->filter_stack_transport() != nullptr) { - ++accept_stream_types; - op->set_accept_stream = true; - op->set_accept_stream_fn = AcceptStream; - op->set_registered_method_matcher_fn = [](void* arg, - ClientMetadata* metadata) { - static_cast(arg)->SetRegisteredMethodOnMetadata(*metadata); - }; - op->set_accept_stream_user_data = this; - } - if (transport->server_transport() != nullptr) { - ++accept_stream_types; - transport->server_transport()->SetAcceptor(this); - } - CHECK_EQ(accept_stream_types, 1); + CHECK(transport->filter_stack_transport() != nullptr); + op->set_accept_stream = true; + op->set_accept_stream_fn = AcceptStream; + op->set_registered_method_matcher_fn = [](void* arg, + ClientMetadata* metadata) { + static_cast(arg)->server_->SetRegisteredMethodOnMetadata( + *metadata); + }; + op->set_accept_stream_user_data = this; op->start_connectivity_watch = MakeOrphanable(this); if (server_->ShutdownCalled()) { op->disconnect_with_error = GRPC_ERROR_CREATE("Server shutdown"); @@ -1350,24 +1409,23 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, transport->PerformOp(op); } -Server::RegisteredMethod* Server::ChannelData::GetRegisteredMethod( +Server::RegisteredMethod* Server::GetRegisteredMethod( const absl::string_view& host, const absl::string_view& path) { - if (server_->registered_methods_.empty()) return nullptr; + if (registered_methods_.empty()) return nullptr; // check for an exact match with host - auto it = server_->registered_methods_.find(std::make_pair(host, path)); - if (it != server_->registered_methods_.end()) { + auto it = registered_methods_.find(std::make_pair(host, path)); + if (it != registered_methods_.end()) { return it->second.get(); } // check for wildcard method definition (no host set) - it = server_->registered_methods_.find(std::make_pair("", path)); - if (it != server_->registered_methods_.end()) { + it = registered_methods_.find(std::make_pair("", path)); + if (it != registered_methods_.end()) { return it->second.get(); } return nullptr; } -void Server::ChannelData::SetRegisteredMethodOnMetadata( - ClientMetadata& metadata) { +void Server::SetRegisteredMethodOnMetadata(ClientMetadata& metadata) { auto* authority = metadata.get_pointer(HttpAuthorityMetadata()); if (authority == nullptr) { authority = metadata.get_pointer(HostMetadata()); @@ -1403,188 +1461,14 @@ void Server::ChannelData::AcceptStream(void* arg, Transport* /*transport*/, grpc_call* call; grpc_error_handle error = grpc_call_create(&args, &call); grpc_call_stack* call_stack = grpc_call_get_call_stack(call); - if (call_stack == nullptr) { // Promise based calls do not have a call stack - CHECK(error.ok()); - CHECK(IsPromiseBasedServerCallEnabled()); + CHECK_NE(call_stack, nullptr); + grpc_call_element* elem = grpc_call_stack_element(call_stack, 0); + auto* calld = static_cast(elem->call_data); + if (!error.ok()) { + calld->FailCallCreation(); return; - } else { - grpc_call_element* elem = grpc_call_stack_element(call_stack, 0); - auto* calld = static_cast(elem->call_data); - if (!error.ok()) { - calld->FailCallCreation(); - return; - } - calld->Start(elem); } -} - -namespace { -auto CancelledDueToServerShutdown() { - return [] { - return ServerMetadataFromStatus(absl::CancelledError("Server shutdown")); - }; -} -} // namespace - -void Server::ChannelData::InitCall(RefCountedPtr call) { - call->SpawnGuarded("request_matcher", [this, call]() { - return TrySeq( - // Wait for initial metadata to pass through all filters - Map(call->PullClientInitialMetadata(), - [](ValueOrFailure md) - -> absl::StatusOr { - if (!md.ok()) { - return absl::InternalError("Missing metadata"); - } - if (!md.value()->get_pointer(HttpPathMetadata())) { - return absl::InternalError("Missing :path header"); - } - if (!md.value()->get_pointer(HttpAuthorityMetadata())) { - return absl::InternalError("Missing :authority header"); - } - return std::move(*md); - }), - // Match request with requested call - [this, call](ClientMetadataHandle md) { - auto* registered_method = static_cast( - md->get(GrpcRegisteredMethod()).value_or(nullptr)); - RequestMatcherInterface* rm; - grpc_server_register_method_payload_handling payload_handling = - GRPC_SRM_PAYLOAD_NONE; - if (registered_method == nullptr) { - rm = server_->unregistered_request_matcher_.get(); - } else { - payload_handling = registered_method->payload_handling; - rm = registered_method->matcher.get(); - } - auto maybe_read_first_message = If( - payload_handling == GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, - [call]() { return call->PullClientToServerMessage(); }, - []() -> ValueOrFailure> { - return ValueOrFailure>( - absl::nullopt); - }); - return TryJoin( - std::move(maybe_read_first_message), rm->MatchRequest(cq_idx()), - [md = std::move(md)]() mutable { - return ValueOrFailure(std::move(md)); - }); - }, - // Publish call to cq - [](std::tuple, - RequestMatcherInterface::MatchResult, - ClientMetadataHandle> - r) { - RequestMatcherInterface::MatchResult& mr = std::get<1>(r); - auto md = std::move(std::get<2>(r)); - auto* rc = mr.TakeCall(); - rc->Complete(std::move(std::get<0>(r)), *md); - auto* call_context = GetContext(); - const auto* deadline = md->get_pointer(GrpcTimeoutMetadata()); - if (deadline != nullptr) { - GetContext()->UpdateDeadline(*deadline); - } - *rc->call = call_context->c_call(); - grpc_call_ref(*rc->call); - grpc_call_set_completion_queue(call_context->c_call(), - rc->cq_bound_to_call); - call_context->server_call_context()->PublishInitialMetadata( - std::move(md), rc->initial_metadata); - // TODO(ctiller): publish metadata - return Map(WaitForCqEndOp(false, rc->tag, absl::OkStatus(), mr.cq()), - [rc = std::unique_ptr(rc)](Empty) { - return absl::OkStatus(); - }); - }); - }); -} - -ArenaPromise Server::ChannelData::MakeCallPromise( - grpc_channel_element* elem, CallArgs call_args, NextPromiseFactory) { - auto* chand = static_cast(elem->channel_data); - auto* server = chand->server_.get(); - if (server->ShutdownCalled()) return CancelledDueToServerShutdown(); - auto cleanup_ref = - absl::MakeCleanup([server] { server->ShutdownUnrefOnRequest(); }); - if (!server->ShutdownRefOnRequest()) return CancelledDueToServerShutdown(); - auto path_ptr = - call_args.client_initial_metadata->get_pointer(HttpPathMetadata()); - if (path_ptr == nullptr) { - return [] { - return ServerMetadataFromStatus( - absl::InternalError("Missing :path header")); - }; - } - auto host_ptr = - call_args.client_initial_metadata->get_pointer(HttpAuthorityMetadata()); - if (host_ptr == nullptr) { - return [] { - return ServerMetadataFromStatus( - absl::InternalError("Missing :authority header")); - }; - } - // Find request matcher. - RequestMatcherInterface* matcher; - RegisteredMethod* rm = static_cast( - call_args.client_initial_metadata->get(GrpcRegisteredMethod()) - .value_or(nullptr)); - ArenaPromise>> - maybe_read_first_message([] { return NextResult(); }); - if (rm != nullptr) { - matcher = rm->matcher.get(); - switch (rm->payload_handling) { - case GRPC_SRM_PAYLOAD_NONE: - break; - case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: - maybe_read_first_message = - Map(call_args.client_to_server_messages->Next(), - [](NextResult msg) - -> absl::StatusOr> { - return std::move(msg); - }); - } - } else { - matcher = server->unregistered_request_matcher_.get(); - } - return TrySeq( - std::move(maybe_read_first_message), - [cleanup_ref = std::move(cleanup_ref), matcher, - chand](NextResult payload) mutable { - return Map( - [cleanup_ref = std::move(cleanup_ref), - mr = matcher->MatchRequest(chand->cq_idx())]() mutable { - return mr(); - }, - [payload = std::move(payload)]( - absl::StatusOr mr) mutable - -> absl::StatusOr>> { - if (!mr.ok()) return mr.status(); - return std::make_pair(std::move(*mr), std::move(payload)); - }); - }, - [call_args = - std::move(call_args)](std::pair> - r) mutable { - auto& mr = r.first; - auto& payload = r.second; - auto* rc = mr.TakeCall(); - auto* cq_for_new_request = mr.cq(); - auto* server_call_context = - GetContext()->server_call_context(); - rc->Complete(std::move(payload), *call_args.client_initial_metadata); - server_call_context->PublishInitialMetadata( - std::move(call_args.client_initial_metadata), rc->initial_metadata); - return server_call_context->MakeTopOfServerCallPromise( - std::move(call_args), rc->cq_bound_to_call, - [rc, cq_for_new_request](grpc_call* call) { - *rc->call = call; - grpc_cq_end_op(cq_for_new_request, rc->tag, absl::OkStatus(), - Server::DoneRequestEvent, rc, &rc->completion, - true); - }); - }); + calld->Start(elem); } void Server::ChannelData::FinishDestroy(void* arg, diff --git a/src/core/server/server.h b/src/core/server/server.h index a4353794a37..01b541c233e 100644 --- a/src/core/server/server.h +++ b/src/core/server/server.h @@ -38,6 +38,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include #include #include #include @@ -215,6 +216,10 @@ class Server : public ServerInterface, void SendGoaways() ABSL_LOCKS_EXCLUDED(mu_global_, mu_call_); + grpc_compression_options compression_options() const override { + return compression_options_; + } + private: // note: the grpc_core::Server redundant namespace qualification is // required for older gcc versions. @@ -227,13 +232,12 @@ class Server : public ServerInterface, struct RequestedCall; class RequestMatcherInterface; - class RealRequestMatcherFilterStack; - class RealRequestMatcherPromises; + class RealRequestMatcher; class AllocatingRequestMatcherBase; class AllocatingRequestMatcherBatch; class AllocatingRequestMatcherRegistered; - class ChannelData final : public ServerTransport::Acceptor { + class ChannelData final { public: ChannelData() = default; ~ChannelData(); @@ -246,26 +250,17 @@ class Server : public ServerInterface, Channel* channel() const { return channel_.get(); } size_t cq_idx() const { return cq_idx_; } - RegisteredMethod* GetRegisteredMethod(const absl::string_view& host, - const absl::string_view& path); // Filter vtable functions. static grpc_error_handle InitChannelElement( grpc_channel_element* elem, grpc_channel_element_args* args); static void DestroyChannelElement(grpc_channel_element* elem); - static ArenaPromise MakeCallPromise( - grpc_channel_element* elem, CallArgs call_args, NextPromiseFactory); void InitCall(RefCountedPtr call); - Arena* CreateArena() override; - absl::StatusOr CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) override; - private: class ConnectivityWatcher; static void AcceptStream(void* arg, Transport* /*transport*/, const void* transport_server_data); - void SetRegisteredMethodOnMetadata(ClientMetadata& metadata); void Destroy() ABSL_EXCLUSIVE_LOCKS_REQUIRED(server_->mu_global_); @@ -396,6 +391,12 @@ class Server : public ServerInterface, using is_transparent = void; }; + class TransportConnectivityWatcher; + + RegisteredMethod* GetRegisteredMethod(const absl::string_view& host, + const absl::string_view& path); + void SetRegisteredMethodOnMetadata(ClientMetadata& metadata); + static void ListenerDestroyDone(void* arg, grpc_error_handle error); static void DoneShutdownEvent(void* server, @@ -457,6 +458,10 @@ class Server : public ServerInterface, return shutdown_refs_.load(std::memory_order_acquire) == 0; } + auto MatchAndPublishCall(CallHandler call_handler); + absl::StatusOr> MakeCallDestination( + const ChannelArgs& args); + ChannelArgs const channel_args_; RefCountedPtr channelz_node_; std::unique_ptr config_fetcher_; @@ -465,6 +470,7 @@ class Server : public ServerInterface, std::vector cqs_; std::vector pollsets_; bool started_ = false; + const grpc_compression_options compression_options_; // The two following mutexes control access to server-state. // mu_global_ controls access to non-call-related state (e.g., channel state). @@ -512,6 +518,9 @@ class Server : public ServerInterface, absl::BitGen bitgen_ ABSL_GUARDED_BY(mu_call_); std::list channels_; + absl::flat_hash_set> connections_ + ABSL_GUARDED_BY(mu_global_); + size_t connections_open_ ABSL_GUARDED_BY(mu_global_) = 0; std::list listeners_; size_t listeners_destroyed_ = 0; diff --git a/src/core/server/server_interface.h b/src/core/server/server_interface.h index 3cb7b1702ff..431ad369714 100644 --- a/src/core/server/server_interface.h +++ b/src/core/server/server_interface.h @@ -17,6 +17,7 @@ #ifndef GRPC_SRC_CORE_SERVER_SERVER_INTERFACE_H #define GRPC_SRC_CORE_SERVER_SERVER_INTERFACE_H +#include #include #include "src/core/channelz/channelz.h" @@ -36,6 +37,7 @@ class ServerInterface { virtual const ChannelArgs& channel_args() const = 0; virtual channelz::ServerNode* channelz_node() const = 0; virtual ServerCallTracerFactory* server_call_tracer_factory() const = 0; + virtual grpc_compression_options compression_options() const = 0; }; } // namespace grpc_core diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 377dac99484..f00614f2c35 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -736,6 +736,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/call_spine.cc', 'src/core/lib/transport/connectivity_state.cc', 'src/core/lib/transport/error_utils.cc', + 'src/core/lib/transport/interception_chain.cc', 'src/core/lib/transport/message.cc', 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', diff --git a/test/core/end2end/tests/filter_context.cc b/test/core/end2end/tests/filter_context.cc index 789a05d94d7..7d53047f971 100644 --- a/test/core/end2end/tests/filter_context.cc +++ b/test/core/end2end/tests/filter_context.cc @@ -103,9 +103,6 @@ CORE_END2END_TEST(CoreEnd2endTest, FilterContext) { CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) { for (auto type : {GRPC_CLIENT_CHANNEL, GRPC_CLIENT_SUBCHANNEL, GRPC_CLIENT_DIRECT_CHANNEL, GRPC_SERVER_CHANNEL}) { - if (type == GRPC_SERVER_CHANNEL && IsPromiseBasedServerCallEnabled()) { - continue; - } builder->channel_init()->RegisterFilter(type, &test_filter); } }); diff --git a/test/core/surface/channel_init_test.cc b/test/core/surface/channel_init_test.cc index 1b0baeafba0..a90777973c3 100644 --- a/test/core/surface/channel_init_test.cc +++ b/test/core/surface/channel_init_test.cc @@ -23,7 +23,10 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack_builder_impl.h" +#include "src/core/lib/channel/promise_based_filter.h" +#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/surface/channel_stack_type.h" +#include "src/core/lib/transport/call_arena_allocator.h" #include "test/core/test_util/test_config.h" namespace grpc_core { @@ -208,7 +211,7 @@ class TestFilter1 { explicit TestFilter1(int* p) : p_(p) {} static absl::StatusOr> Create( - const ChannelArgs& args, Empty) { + const ChannelArgs& args, ChannelFilter::Args) { EXPECT_EQ(args.GetInt("foo"), 1); return std::make_unique(args.GetPointer("p")); } @@ -250,19 +253,23 @@ TEST(ChannelInitTest, CanCreateFilterWithCall) { b.RegisterFilter(GRPC_CLIENT_CHANNEL); auto init = b.Build(); int p = 0; - auto segment = init.CreateStackSegment( - GRPC_CLIENT_CHANNEL, - ChannelArgs().Set("foo", 1).Set("p", ChannelArgs::UnownedPointer(&p))); - ASSERT_TRUE(segment.ok()) << segment.status(); - CallFilters::StackBuilder stack_builder; - segment->AddToCallFilterStack(stack_builder); - segment = absl::CancelledError(); // force the segment to be destroyed - auto stack = stack_builder.Build(); - { - CallFilters call_filters(Arena::MakePooled()); - call_filters.SetStack(std::move(stack)); - } + InterceptionChainBuilder chain_builder{ + ChannelArgs().Set("foo", 1).Set("p", ChannelArgs::UnownedPointer(&p))}; + init.AddToInterceptionChainBuilder(GRPC_CLIENT_CHANNEL, chain_builder); + int handled = 0; + auto stack = chain_builder.Build(MakeCallDestinationFromHandlerFunction( + [&handled](CallHandler) { ++handled; })); + ASSERT_TRUE(stack.ok()) << stack.status(); + RefCountedPtr allocator = + MakeRefCounted( + ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator( + "test"), + 1024); + auto call = MakeCallPair(Arena::MakePooled(), nullptr, + allocator->MakeArena(), allocator, nullptr); + (*stack)->StartCall(std::move(call.handler)); EXPECT_EQ(p, 1); + EXPECT_EQ(handled, 1); } } // namespace diff --git a/test/core/transport/chaotic_good/chaotic_good_server_test.cc b/test/core/transport/chaotic_good/chaotic_good_server_test.cc index b5b058b43ee..40de0b35cbe 100644 --- a/test/core/transport/chaotic_good/chaotic_good_server_test.cc +++ b/test/core/transport/chaotic_good/chaotic_good_server_test.cc @@ -39,6 +39,7 @@ #include "src/core/lib/uri/uri_parser.h" #include "src/core/server/server.h" #include "test/core/event_engine/event_engine_test_utils.h" +#include "test/core/test_util/build.h" #include "test/core/test_util/port.h" #include "test/core/test_util/test_config.h" @@ -67,7 +68,10 @@ class ChaoticGoodServerTest : public ::testing::Test { auto ev = grpc_completion_queue_pluck( shutdown_cq, nullptr, grpc_timeout_milliseconds_to_deadline(15000), nullptr); - CHECK(ev.type == GRPC_OP_COMPLETE); + if (ev.type == GRPC_QUEUE_TIMEOUT) { + AsanAssertNoLeaks(); + } + CHECK_EQ(ev.type, GRPC_OP_COMPLETE); CHECK_EQ(ev.tag, nullptr); grpc_completion_queue_destroy(shutdown_cq); grpc_server_destroy(server_); diff --git a/test/core/transport/chaotic_good/server_transport_test.cc b/test/core/transport/chaotic_good/server_transport_test.cc index a5dd0008b9a..da80f94781f 100644 --- a/test/core/transport/chaotic_good/server_transport_test.cc +++ b/test/core/transport/chaotic_good/server_transport_test.cc @@ -82,19 +82,19 @@ ServerMetadataHandle TestTrailingMetadata() { return md; } -class MockAcceptor : public ServerTransport::Acceptor { +class MockCallDestination : public UnstartedCallDestination { public: - virtual ~MockAcceptor() = default; - MOCK_METHOD(Arena*, CreateArena, (), (override)); - MOCK_METHOD(absl::StatusOr, CreateCall, - (ClientMetadataHandle client_initial_metadata, Arena* arena), + ~MockCallDestination() override = default; + MOCK_METHOD(void, Orphaned, (), (override)); + MOCK_METHOD(void, StartCall, (UnstartedCallHandler unstarted_call_handler), (override)); }; TEST_F(TransportTest, ReadAndWriteOneMessage) { MockPromiseEndpoint control_endpoint; MockPromiseEndpoint data_endpoint; - StrictMock acceptor; + auto call_destination = MakeRefCounted>(); + EXPECT_CALL(*call_destination, Orphaned()).Times(1); auto transport = MakeOrphanable( CoreConfiguration::Get() .channel_args_preconditioning() @@ -112,19 +112,21 @@ TEST_F(TransportTest, ReadAndWriteOneMessage) { data_endpoint.ExpectRead( {EventEngineSlice::FromCopiedString("12345678"), Zeros(56)}, nullptr); // Once that's read we'll create a new call - auto* call_arena = MakeArena(); - EXPECT_CALL(acceptor, CreateArena).WillOnce(Return(call_arena)); StrictMock> on_done; - EXPECT_CALL(acceptor, CreateCall(_, call_arena)) - .WillOnce(WithArgs<0>([this, call_arena, &on_done]( - ClientMetadataHandle client_initial_metadata) { - EXPECT_EQ(client_initial_metadata->get_pointer(HttpPathMetadata()) + auto control_address = + grpc_event_engine::experimental::URIToResolvedAddress("ipv4:1.2.3.4:5678") + .value(); + EXPECT_CALL(*control_endpoint.endpoint, GetPeerAddress) + .WillRepeatedly([&control_address]() { return control_address; }); + EXPECT_CALL(*call_destination, StartCall(_)) + .WillOnce(WithArgs<0>([&on_done]( + UnstartedCallHandler unstarted_call_handler) { + EXPECT_EQ(unstarted_call_handler.UnprocessedClientInitialMetadata() + .get_pointer(HttpPathMetadata()) ->as_string_view(), "/demo.Service/Step"); - CallInitiatorAndHandler call = MakeCallPair( - std::move(client_initial_metadata), event_engine().get(), - call_arena, call_arena_allocator(), nullptr); - auto handler = call.handler.V2HackToStartCallWithoutACallFilterStack(); + auto handler = + unstarted_call_handler.V2HackToStartCallWithoutACallFilterStack(); handler.SpawnInfallible("test-io", [&on_done, handler]() mutable { return Seq( handler.PullClientInitialMetadata(), @@ -163,9 +165,8 @@ TEST_F(TransportTest, ReadAndWriteOneMessage) { return Empty{}; }); }); - return std::move(call.initiator); })); - transport->SetAcceptor(&acceptor); + transport->SetCallDestination(call_destination); EXPECT_CALL(on_done, Call()); EXPECT_CALL(*control_endpoint.endpoint, Read) .InSequence(control_endpoint.read_sequence) diff --git a/test/core/transport/test_suite/call_content.cc b/test/core/transport/test_suite/call_content.cc index 9e334f24fb6..cfcac0bf91b 100644 --- a/test/core/transport/test_suite/call_content.cc +++ b/test/core/transport/test_suite/call_content.cc @@ -62,7 +62,7 @@ void FillMetadata(const std::vector>& md, } // namespace TRANSPORT_TEST(UnaryWithSomeContent) { - SetServerAcceptor(); + SetServerCallDestination(); const auto client_initial_metadata = RandomMetadata(); const auto server_initial_metadata = RandomMetadata(); const auto server_trailing_metadata = RandomMetadata(); diff --git a/test/core/transport/test_suite/call_shapes.cc b/test/core/transport/test_suite/call_shapes.cc index fdae653119d..89ee26ccd2f 100644 --- a/test/core/transport/test_suite/call_shapes.cc +++ b/test/core/transport/test_suite/call_shapes.cc @@ -17,7 +17,7 @@ namespace grpc_core { TRANSPORT_TEST(MetadataOnlyRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -72,7 +72,7 @@ TRANSPORT_TEST(MetadataOnlyRequestServerAbortsAfterInitialMetadata) { "wrong status code: we don't care for any cases we're " "rolling out soon, so leaving this disabled."; - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -125,7 +125,7 @@ TRANSPORT_TEST(MetadataOnlyRequestServerAbortsImmediately) { "wrong status code: we don't care for any cases we're " "rolling out soon, so leaving this disabled."; - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -165,7 +165,7 @@ TRANSPORT_TEST(MetadataOnlyRequestServerAbortsImmediately) { } TRANSPORT_TEST(CanCreateCallThenAbandonIt) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -178,7 +178,7 @@ TRANSPORT_TEST(CanCreateCallThenAbandonIt) { } TRANSPORT_TEST(UnaryRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -257,7 +257,7 @@ TRANSPORT_TEST(UnaryRequest) { } TRANSPORT_TEST(UnaryRequestOmitCheckEndOfStream) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -326,7 +326,7 @@ TRANSPORT_TEST(UnaryRequestOmitCheckEndOfStream) { } TRANSPORT_TEST(UnaryRequestWaitForServerInitialMetadataBeforeSendingPayload) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -404,7 +404,7 @@ TRANSPORT_TEST(UnaryRequestWaitForServerInitialMetadataBeforeSendingPayload) { } TRANSPORT_TEST(ClientStreamingRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -518,7 +518,7 @@ TRANSPORT_TEST(ClientStreamingRequest) { } TRANSPORT_TEST(ServerStreamingRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); diff --git a/test/core/transport/test_suite/inproc_fixture.cc b/test/core/transport/test_suite/inproc_fixture.cc index 357bbef66be..65468229341 100644 --- a/test/core/transport/test_suite/inproc_fixture.cc +++ b/test/core/transport/test_suite/inproc_fixture.cc @@ -13,12 +13,16 @@ // limitations under the License. #include "src/core/ext/transport/inproc/inproc_transport.h" +#include "src/core/lib/config/core_configuration.h" #include "test/core/transport/test_suite/fixture.h" namespace grpc_core { TRANSPORT_FIXTURE(Inproc) { - auto transports = MakeInProcessTransportPair(); + auto transports = + MakeInProcessTransportPair(CoreConfiguration::Get() + .channel_args_preconditioning() + .PreconditionChannelArgs(nullptr)); return {std::move(transports.first), std::move(transports.second)}; } diff --git a/test/core/transport/test_suite/no_op.cc b/test/core/transport/test_suite/no_op.cc index 0efd226257d..26e21e44e32 100644 --- a/test/core/transport/test_suite/no_op.cc +++ b/test/core/transport/test_suite/no_op.cc @@ -20,8 +20,8 @@ TRANSPORT_TEST(NoOp) {} TRANSPORT_TEST(WaitForAllPendingWork) { WaitForAllPendingWork(); } -TRANSPORT_TEST(SetServerAcceptorAndFinish) { - SetServerAcceptor(); +TRANSPORT_TEST(SetServerCallDestinationAndFinish) { + SetServerCallDestination(); WaitForAllPendingWork(); } diff --git a/test/core/transport/test_suite/stress.cc b/test/core/transport/test_suite/stress.cc index ca20fb7ff3f..e791bb18b8f 100644 --- a/test/core/transport/test_suite/stress.cc +++ b/test/core/transport/test_suite/stress.cc @@ -19,7 +19,7 @@ namespace grpc_core { TRANSPORT_TEST(ManyUnaryRequests) { - SetServerAcceptor(); + SetServerCallDestination(); const int kNumRequests = absl::LogUniform(rng(), 10, 100); std::list call_names; auto make_call_name = [&call_names](int i, diff --git a/test/core/transport/test_suite/test.cc b/test/core/transport/test_suite/test.cc index e170c9acda6..c228196983e 100644 --- a/test/core/transport/test_suite/test.cc +++ b/test/core/transport/test_suite/test.cc @@ -52,8 +52,9 @@ void TransportTest::RunTest() { event_engine_->UnsetGlobalHooks(); } -void TransportTest::SetServerAcceptor() { - transport_pair_.server->server_transport()->SetAcceptor(&acceptor_); +void TransportTest::SetServerCallDestination() { + transport_pair_.server->server_transport()->SetCallDestination( + server_call_destination_); } CallInitiator TransportTest::CreateCall( @@ -71,8 +72,10 @@ CallInitiator TransportTest::CreateCall( CallHandler TransportTest::TickUntilServerCall() { WatchDog watchdog(this); for (;;) { - auto handler = acceptor_.PopHandler(); - if (handler.has_value()) return std::move(*handler); + auto handler = server_call_destination_->PopHandler(); + if (handler.has_value()) { + return std::move(*handler); + } event_engine_->Tick(); } } @@ -227,22 +230,14 @@ std::string TransportTest::RandomMessage() { } /////////////////////////////////////////////////////////////////////////////// -// TransportTest::Acceptor - -Arena* TransportTest::Acceptor::CreateArena() { - return test_->call_arena_allocator_->MakeArena(); -} +// TransportTest::ServerCallDestination -absl::StatusOr TransportTest::Acceptor::CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) { - auto call = MakeCallPair(std::move(client_initial_metadata), - test_->event_engine_.get(), arena, - test_->call_arena_allocator_, nullptr); - handlers_.push(call.handler.V2HackToStartCallWithoutACallFilterStack()); - return std::move(call.initiator); +void TransportTest::ServerCallDestination::StartCall( + UnstartedCallHandler handler) { + handlers_.push(handler.V2HackToStartCallWithoutACallFilterStack()); } -absl::optional TransportTest::Acceptor::PopHandler() { +absl::optional TransportTest::ServerCallDestination::PopHandler() { if (!handlers_.empty()) { auto handler = std::move(handlers_.front()); handlers_.pop(); diff --git a/test/core/transport/test_suite/test.h b/test/core/transport/test_suite/test.h index 1add21cdd29..841b8cedfc8 100644 --- a/test/core/transport/test_suite/test.h +++ b/test/core/transport/test_suite/test.h @@ -32,6 +32,7 @@ #include "src/core/lib/resource_quota/resource_quota.h" #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h" #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h" +#include "test/core/test_util/test_config.h" #include "test/core/transport/test_suite/fixture.h" namespace grpc_core { @@ -220,7 +221,7 @@ class TransportTest : public ::testing::Test { fixture_(std::move(fixture)), rng_(rng) {} - void SetServerAcceptor(); + void SetServerCallDestination(); CallInitiator CreateCall(ClientMetadataHandle client_initial_metadata); std::string RandomString(int min_length, int max_length, @@ -270,18 +271,14 @@ class TransportTest : public ::testing::Test { void Timeout(); - class Acceptor final : public ServerTransport::Acceptor { + class ServerCallDestination final : public UnstartedCallDestination { public: - explicit Acceptor(TransportTest* test) : test_(test) {} - - Arena* CreateArena() override; - absl::StatusOr CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) override; + void StartCall(UnstartedCallHandler unstarted_call_handler) override; + void Orphaned() override {} absl::optional PopHandler(); private: std::queue handlers_; - TransportTest* const test_; }; class WatchDog { @@ -296,6 +293,7 @@ class TransportTest : public ::testing::Test { [this]() { test_->Timeout(); })}; }; + grpc::testing::TestGrpcScope grpc_scope_; std::shared_ptr event_engine_{ std::make_shared( @@ -313,7 +311,8 @@ class TransportTest : public ::testing::Test { ->memory_quota() ->CreateMemoryAllocator("test-allocator"), 1024)}; - Acceptor acceptor_{this}; + RefCountedPtr server_call_destination_ = + MakeRefCounted(); TransportFixture::ClientAndServerTransportPair transport_pair_ = fixture_->CreateTransportPair(event_engine_); std::queue> diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc index 04a8f010cd5..b79df3ed4d1 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc @@ -111,7 +111,6 @@ int main(int argc, char** argv) { grpc_core::ForceEnableExperiment("event_engine_client", true); grpc_core::ForceEnableExperiment("event_engine_listener", true); grpc_core::ForceEnableExperiment("promise_based_client_call", true); - grpc_core::ForceEnableExperiment("promise_based_server_call", true); grpc_core::ForceEnableExperiment("chaotic_good", true); grpc::testing::TestEnvironment env(&argc, argv); LibraryInitializer libInit; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 02efb7460b9..649e1eb576a 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2750,6 +2750,7 @@ src/core/lib/transport/bdp_estimator.cc \ src/core/lib/transport/bdp_estimator.h \ src/core/lib/transport/call_arena_allocator.cc \ src/core/lib/transport/call_arena_allocator.h \ +src/core/lib/transport/call_destination.h \ src/core/lib/transport/call_filters.cc \ src/core/lib/transport/call_filters.h \ src/core/lib/transport/call_final_info.cc \ @@ -2762,6 +2763,8 @@ src/core/lib/transport/custom_metadata.h \ src/core/lib/transport/error_utils.cc \ src/core/lib/transport/error_utils.h \ src/core/lib/transport/http2_errors.h \ +src/core/lib/transport/interception_chain.cc \ +src/core/lib/transport/interception_chain.h \ src/core/lib/transport/message.cc \ src/core/lib/transport/message.h \ src/core/lib/transport/metadata.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index f98a7a95a21..d3a4f44a588 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -2527,6 +2527,7 @@ src/core/lib/transport/bdp_estimator.cc \ src/core/lib/transport/bdp_estimator.h \ src/core/lib/transport/call_arena_allocator.cc \ src/core/lib/transport/call_arena_allocator.h \ +src/core/lib/transport/call_destination.h \ src/core/lib/transport/call_filters.cc \ src/core/lib/transport/call_filters.h \ src/core/lib/transport/call_final_info.cc \ @@ -2539,6 +2540,8 @@ src/core/lib/transport/custom_metadata.h \ src/core/lib/transport/error_utils.cc \ src/core/lib/transport/error_utils.h \ src/core/lib/transport/http2_errors.h \ +src/core/lib/transport/interception_chain.cc \ +src/core/lib/transport/interception_chain.h \ src/core/lib/transport/message.cc \ src/core/lib/transport/message.h \ src/core/lib/transport/metadata.cc \