From 61a841b2081bb6753845b54c4f8b53bc18c1977a Mon Sep 17 00:00:00 2001 From: Gregory Cooke Date: Thu, 4 Jan 2024 11:40:47 -0800 Subject: [PATCH 01/27] Disable failing openssl102 tests (#35354) There are a select few tests that are failing when building with OpenSSL102 - disable them until we can fix. Closes #35354 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35354 from gtcooke94:fix_ossl_102 8708d6ce861ca719f312719d6172c025241bd2f6 PiperOrigin-RevId: 595761932 --- test/core/tsi/ssl_transport_security_test.cc | 6 +++++- test/cpp/end2end/crl_provider_test.cc | 4 ++++ test/cpp/end2end/tls_credentials_test.cc | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index dae69e58c75..98b1d739d64 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -1278,7 +1278,6 @@ TEST(SslTransportSecurityTest, MainTest) { 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_skipping_server_certificate_verification(); ssl_tsi_test_do_handshake_with_large_server_handshake_messages( trust_bundle); ssl_tsi_test_do_handshake_with_client_authentication(); @@ -1289,6 +1288,11 @@ TEST(SslTransportSecurityTest, MainTest) { 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(); diff --git a/test/cpp/end2end/crl_provider_test.cc b/test/cpp/end2end/crl_provider_test.cc index 180da59eb0e..6902fd7443e 100644 --- a/test/cpp/end2end/crl_provider_test.cc +++ b/test/cpp/end2end/crl_provider_test.cc @@ -49,6 +49,8 @@ #include "test/core/util/tls_utils.h" #include "test/cpp/end2end/test_service_impl.h" +// CRL Providers not supported for <1.1 +#if OPENSSL_VERSION_NUMBER >= 0x10100000 namespace grpc { namespace testing { namespace { @@ -280,6 +282,8 @@ TEST_F(CrlProviderTest, CrlProviderValidReloaderProvider) { } // namespace testing } // namespace grpc +#endif // OPENSSL_VERSION_NUMBER >= 0x10100000 + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(&argc, argv); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/cpp/end2end/tls_credentials_test.cc b/test/cpp/end2end/tls_credentials_test.cc index a0a78e684be..24f83d6f898 100644 --- a/test/cpp/end2end/tls_credentials_test.cc +++ b/test/cpp/end2end/tls_credentials_test.cc @@ -107,6 +107,7 @@ class TlsCredentialsTest : public ::testing::Test { std::string server_addr_; }; +// NOLINTNEXTLINE(clang-diagnostic-unused-function) void DoRpc(const std::string& server_addr, const TlsChannelCredentialsOptions& tls_options) { std::shared_ptr channel = From a3e24ed692cd62dc0691cf15c9ec6d771deadc88 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 4 Jan 2024 18:26:10 -0800 Subject: [PATCH 02/27] [FuzzingEventEngine] add time padding to avoid busy loops (#35447) We encountered an api_fuzzer test case that adds a huge number of addresses that all immediately fail to connect, but it set max_backoff to 0, so there was a giant busy loop where pick_first was constantly trying to connect to subchannels with no delay. The FuzzingEventEngine was getting stuck in a tick loop, always accumulating more tasks that needed to be executed immediately, so it could never make forward progress on the test case. This PR fixes the problem by adding a fixed 1us delay if the task's delay is 0 and the test case has not provided any more fixed delays. (Unfortunately, I cannot include the test case that triggered the problem in this PR, because it winds up exceeding the RBE stdout limit.) Fixes b/310664846. Closes #35447 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35447 from markdroth:api_fuzzer_busy_loop_fix 90055d3d927927ff25b0e3e35cdca303479f661c PiperOrigin-RevId: 595853516 --- .../fuzzing_event_engine/fuzzing_event_engine.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc b/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc index c788c43cee3..404781ee5b7 100644 --- a/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc +++ b/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc @@ -543,11 +543,18 @@ EventEngine::TaskHandle FuzzingEventEngine::RunAfterLocked( const intptr_t id = next_task_id_; ++next_task_id_; Duration delay_taken = Duration::zero(); - if (run_type != RunType::kExact && !task_delays_.empty()) { - delay_taken = grpc_core::Clamp(task_delays_.front(), Duration::zero(), - max_delay_[static_cast(run_type)]); + if (run_type != RunType::kExact) { + if (!task_delays_.empty()) { + delay_taken = grpc_core::Clamp(task_delays_.front(), Duration::zero(), + max_delay_[static_cast(run_type)]); + task_delays_.pop(); + } else if (run_type != RunType::kWrite && when == Duration::zero()) { + // For zero-duration events, if there is no more delay input from + // the test case, we default to a small non-zero value to avoid + // busy loops that prevent us from making forward progress. + delay_taken = std::chrono::microseconds(1); + } when += delay_taken; - task_delays_.pop(); } auto task = std::make_shared(id, std::move(closure)); tasks_by_id_.emplace(id, task); From f82f8966f0683b5272810f50a81873ba8239ac64 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 5 Jan 2024 08:43:11 -0800 Subject: [PATCH 03/27] [promise] Add a facility to delay promise execution until after the current poll (#35413) Mirrors what we had with combiner, but allows it to occur at arbitrary points. We'll use this in chaotic-good to: 1. combine fragments into a single frame 2. combine writes from different calls into a single syscall Closes #35413 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35413 from ctiller:group-on 9f20f34523b27d87d9cf516487ff9cf0fa81f8df PiperOrigin-RevId: 596004767 --- src/core/lib/promise/party.cc | 64 +++++++++++++++++---------------- src/core/lib/promise/party.h | 45 ++++++++++++++++++++--- test/core/promise/party_test.cc | 48 +++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 35 deletions(-) diff --git a/src/core/lib/promise/party.cc b/src/core/lib/promise/party.cc index 275d06445a4..d2cf5177f93 100644 --- a/src/core/lib/promise/party.cc +++ b/src/core/lib/promise/party.cc @@ -227,40 +227,42 @@ void Party::RunLocked() { bool Party::RunParty() { ScopedActivity activity(this); promise_detail::Context arena_ctx(arena_); - return sync_.RunParty([this](int i) { - // If the participant is null, skip. - // This allows participants to complete whilst wakers still exist - // somewhere. - auto* participant = participants_[i].load(std::memory_order_acquire); - if (participant == nullptr) { - if (grpc_trace_promise_primitives.enabled()) { - gpr_log(GPR_DEBUG, "%s[party] wakeup %d already complete", - DebugTag().c_str(), i); - } - return false; - } - absl::string_view name; + return sync_.RunParty([this](int i) { return RunOneParticipant(i); }); +} + +bool Party::RunOneParticipant(int i) { + // If the participant is null, skip. + // This allows participants to complete whilst wakers still exist + // somewhere. + auto* participant = participants_[i].load(std::memory_order_acquire); + if (participant == nullptr) { if (grpc_trace_promise_primitives.enabled()) { - name = participant->name(); - gpr_log(GPR_DEBUG, "%s[%s] begin job %d", DebugTag().c_str(), - std::string(name).c_str(), i); + gpr_log(GPR_DEBUG, "%s[party] wakeup %d already complete", + DebugTag().c_str(), i); } - // Poll the participant. - currently_polling_ = i; - bool done = participant->PollParticipantPromise(); - currently_polling_ = kNotPolling; - if (done) { - if (!name.empty()) { - gpr_log(GPR_DEBUG, "%s[%s] end poll and finish job %d", - DebugTag().c_str(), std::string(name).c_str(), i); - } - participants_[i].store(nullptr, std::memory_order_relaxed); - } else if (!name.empty()) { - gpr_log(GPR_DEBUG, "%s[%s] end poll", DebugTag().c_str(), - std::string(name).c_str()); + return false; + } + absl::string_view name; + if (grpc_trace_promise_primitives.enabled()) { + name = participant->name(); + gpr_log(GPR_DEBUG, "%s[%s] begin job %d", DebugTag().c_str(), + std::string(name).c_str(), i); + } + // Poll the participant. + currently_polling_ = i; + bool done = participant->PollParticipantPromise(); + currently_polling_ = kNotPolling; + if (done) { + if (!name.empty()) { + gpr_log(GPR_DEBUG, "%s[%s] end poll and finish job %d", + DebugTag().c_str(), std::string(name).c_str(), i); } - return done; - }); + participants_[i].store(nullptr, std::memory_order_relaxed); + } else if (!name.empty()) { + gpr_log(GPR_DEBUG, "%s[%s] end poll", DebugTag().c_str(), + std::string(name).c_str()); + } + return done; } void Party::AddParticipants(Participant** participants, size_t count) { diff --git a/src/core/lib/promise/party.h b/src/core/lib/promise/party.h index 1ff098f3aa3..a6c0aca1789 100644 --- a/src/core/lib/promise/party.h +++ b/src/core/lib/promise/party.h @@ -102,7 +102,8 @@ class PartySyncUsingAtomics { template GRPC_MUST_USE_RESULT bool RunParty(F poll_one_participant) { uint64_t prev_state; - do { + iteration_.fetch_add(1, std::memory_order_relaxed); + for (;;) { // Grab the current state, and clear the wakeup bits & add flag. prev_state = state_.fetch_and(kRefMask | kLocked | kAllocatedMask, std::memory_order_acquire); @@ -133,9 +134,23 @@ class PartySyncUsingAtomics { // TODO(ctiller): consider mitigations for the accidental wakeup on owning // waker creation case -- I currently expect this will be more expensive // than this quick loop. - } while (!state_.compare_exchange_weak( - prev_state, (prev_state & (kRefMask | kAllocatedMask)), - std::memory_order_acq_rel, std::memory_order_acquire)); + if (wake_after_poll_ == 0) { + if (state_.compare_exchange_weak( + prev_state, (prev_state & (kRefMask | kAllocatedMask)), + std::memory_order_acq_rel, std::memory_order_acquire)) { + return false; + } + } else { + if (state_.compare_exchange_weak( + prev_state, + (prev_state & (kRefMask | kAllocatedMask | kLocked)) | + wake_after_poll_, + std::memory_order_acq_rel, std::memory_order_acquire)) { + iteration_.fetch_add(1, std::memory_order_relaxed); + wake_after_poll_ = 0; + } + } + } return false; } @@ -186,6 +201,11 @@ class PartySyncUsingAtomics { // Returns true if the caller should run the party. GRPC_MUST_USE_RESULT bool ScheduleWakeup(WakeupMask mask); + void WakeAfterPoll(WakeupMask mask) { wake_after_poll_ |= mask; } + uint32_t iteration() const { + return iteration_.load(std::memory_order_relaxed); + } + private: bool UnreffedLast(); @@ -225,6 +245,8 @@ class PartySyncUsingAtomics { static constexpr uint64_t kOneRef = 1ull << kRefShift; std::atomic state_; + std::atomic iteration_{0}; + WakeupMask wake_after_poll_ = 0; }; class PartySyncUsingMutex { @@ -358,6 +380,20 @@ class Party : public Activity, private Wakeable { Arena* arena() const { return arena_; } + // Return a promise that resolves to Empty{} when the current party poll is + // complete. + // This is useful for implementing batching and the like: we can hold some + // action until the rest of the party resolves itself. + auto AfterCurrentPoll() { + GPR_DEBUG_ASSERT(Activity::current() == this); + sync_.WakeAfterPoll(CurrentParticipant()); + return [this, iteration = sync_.iteration()]() -> Poll { + GPR_DEBUG_ASSERT(Activity::current() == this); + if (iteration == sync_.iteration()) return Pending{}; + return Empty{}; + }; + } + class BulkSpawner { public: explicit BulkSpawner(Party* party) : party_(party) {} @@ -548,6 +584,7 @@ class Party : public Activity, private Wakeable { // Add a participant (backs Spawn, after type erasure to ParticipantFactory). void AddParticipants(Participant** participant, size_t count); + bool RunOneParticipant(int i); virtual grpc_event_engine::experimental::EventEngine* event_engine() const = 0; diff --git a/test/core/promise/party_test.cc b/test/core/promise/party_test.cc index 551443ac4d5..6f915c26805 100644 --- a/test/core/promise/party_test.cc +++ b/test/core/promise/party_test.cc @@ -490,6 +490,54 @@ TEST_F(PartyTest, CanBulkSpawn) { n2.WaitForNotification(); } +TEST_F(PartyTest, AfterCurrentPollWorks) { + auto party = MakeRefCounted(); + Notification n; + int state = 0; + { + Party::BulkSpawner spawner(party.get()); + // BulkSpawner will schedule and poll this promise first, but the + // `AfterCurrentPoll` will pause it. + // Then spawn1, spawn2, and spawn3 will run in order (with EXPECT_EQ checks + // demonstrating this), at which point the poll will complete, causing + // spawn_final to be awoken and scheduled and see the final state. + spawner.Spawn( + "spawn_final", + [&state, &party]() { + return Seq(party->AfterCurrentPoll(), [&state]() { + EXPECT_EQ(state, 3); + return Empty{}; + }); + }, + [&n](Empty) { n.Notify(); }); + spawner.Spawn( + "spawn1", + [&state]() { + EXPECT_EQ(state, 0); + state = 1; + return Empty{}; + }, + [](Empty) {}); + spawner.Spawn( + "spawn2", + [&state]() { + EXPECT_EQ(state, 1); + state = 2; + return Empty{}; + }, + [](Empty) {}); + spawner.Spawn( + "spawn3", + [&state]() { + EXPECT_EQ(state, 2); + state = 3; + return Empty{}; + }, + [](Empty) {}); + } + n.WaitForNotification(); +} + TEST_F(PartyTest, ThreadStressTest) { auto party = MakeRefCounted(); std::vector threads; From 5923e6cd1e0ddfa8b98ad7f536c8fdf9f95f3605 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 5 Jan 2024 08:58:05 -0800 Subject: [PATCH 04/27] [LB policies] avoid looping over all endpoints/addresses (#35445) This should slightly increase per-channel memory but will eliminate some O(n^2) loops with large numbers of endpoints or addresses. Closes #35445 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35445 from markdroth:lb_policies_remove_unnecessary_loop 94465f44eccf6d1e1974d48b0db14a1d1ef1eeb4 PiperOrigin-RevId: 596007480 --- .../client_channel/lb_policy/endpoint_list.cc | 10 +++------- .../client_channel/lb_policy/endpoint_list.h | 5 ++++- .../lb_policy/pick_first/pick_first.cc | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc index 7f2ecdd69f0..9c74cb8bb9a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +++ b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc @@ -69,6 +69,9 @@ class EndpointList::Endpoint::Helper grpc_connectivity_state state, const absl::Status& status, RefCountedPtr picker) override { auto old_state = std::exchange(endpoint_->connectivity_state_, state); + if (!old_state.has_value()) { + ++endpoint_->endpoint_list_->num_endpoints_seen_initial_state_; + } endpoint_->picker_ = std::move(picker); endpoint_->OnStateUpdate(old_state, state, status); } @@ -181,11 +184,4 @@ void EndpointList::ResetBackoffLocked() { } } -bool EndpointList::AllEndpointsSeenInitialState() const { - for (const auto& endpoint : endpoints_) { - if (!endpoint->connectivity_state().has_value()) return false; - } - return true; -} - } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h index c814d9f50eb..8977dabf9ce 100644 --- a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h @@ -199,7 +199,9 @@ class EndpointList : public InternallyRefCounted { // Returns true if all endpoints have seen their initial connectivity // state notification. - bool AllEndpointsSeenInitialState() const; + bool AllEndpointsSeenInitialState() const { + return num_endpoints_seen_initial_state_ == size(); + } private: // Returns the parent policy's helper. Needed because the accessor @@ -210,6 +212,7 @@ class EndpointList : public InternallyRefCounted { RefCountedPtr policy_; const char* tracer_; std::vector> endpoints_; + size_t num_endpoints_seen_initial_state_ = 0; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index efc0ec90cba..f2f9c8870fb 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -224,7 +224,9 @@ class PickFirst : public LoadBalancingPolicy { private: // Returns true if all subchannels have seen their initial // connectivity state notifications. - bool AllSubchannelsSeenInitialState(); + bool AllSubchannelsSeenInitialState() const { + return num_subchannels_seen_initial_notification_ == size(); + } // Looks through subchannels_ starting from attempting_index_ to // find the first one not currently in TRANSIENT_FAILURE, then @@ -255,6 +257,8 @@ class PickFirst : public LoadBalancingPolicy { // TODO(roth): Remove this when we remove the Happy Eyeballs experiment. bool in_transient_failure_ = false; + size_t num_subchannels_seen_initial_notification_ = 0; + // The index into subchannels_ to which we are currently attempting // to connect during the initial Happy Eyeballs pass. Once the // initial pass is over, this will be equal to size(). @@ -754,6 +758,11 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange( seen_transient_failure_ = true; subchannel_list_->last_failure_ = connectivity_status_; } + // If this is the initial connectivity state update for this subchannel, + // increment the counter in the subchannel list. + if (!old_state.has_value()) { + ++subchannel_list_->num_subchannels_seen_initial_notification_; + } // If we haven't yet seen the initial connectivity state notification // for all subchannels, do nothing. if (!subchannel_list_->AllSubchannelsSeenInitialState()) return; @@ -1122,13 +1131,6 @@ void PickFirst::SubchannelList::ResetBackoffLocked() { } } -bool PickFirst::SubchannelList::AllSubchannelsSeenInitialState() { - for (auto& sd : subchannels_) { - if (!sd.connectivity_state().has_value()) return false; - } - return true; -} - void PickFirst::SubchannelList::StartConnectingNextSubchannel() { // Find the next subchannel not in state TRANSIENT_FAILURE. // We skip subchannels in state TRANSIENT_FAILURE to avoid a From fede9051e1d05786618349f18f4e62b959f6fccd Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 5 Jan 2024 09:28:35 -0800 Subject: [PATCH 05/27] [call-v3] Begin migration of channel_init to templates. Eventually for call-v3 we're going to want to have registration of filters generate the appropriate glue into the channel runtime to execute a call. Begin that process now and gradually by introducing the new syntax and allowing a piecemeal migration to it - by the time we're done converting filters to the v3 APIs we'll also have the registration piece done. PiperOrigin-RevId: 596013927 --- .../backend_metrics/backend_metric_filter.cc | 15 +++--- .../channel_idle/channel_idle_filter.cc | 4 +- .../legacy_channel_idle_filter.cc | 4 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 3 +- .../service_config_channel_arg_filter.cc | 2 +- .../filters/http/client_authority_filter.cc | 9 ++-- .../ext/filters/http/http_filters_plugin.cc | 48 ++++++++++--------- .../ext/filters/logging/logging_filter.cc | 4 +- .../message_size/message_size_filter.cc | 8 ++-- .../lib/channel/server_call_tracer_filter.cc | 4 +- src/core/lib/surface/builtins.cc | 2 +- src/core/lib/surface/channel_init.h | 26 ++++++++++ src/core/lib/surface/init.cc | 11 +++-- test/core/end2end/tests/http2_stats.cc | 4 +- 14 files changed, 86 insertions(+), 58 deletions(-) diff --git a/src/core/ext/filters/backend_metrics/backend_metric_filter.cc b/src/core/ext/filters/backend_metrics/backend_metric_filter.cc index 620101d98cf..185825cb91d 100644 --- a/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +++ b/src/core/ext/filters/backend_metrics/backend_metric_filter.cc @@ -190,12 +190,15 @@ void BackendMetricFilter::Call::OnServerTrailingMetadata(ServerMetadata& md) { } void RegisterBackendMetricFilter(CoreConfiguration::Builder* builder) { - builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, - IsV3BackendMetricFilterEnabled() - ? &BackendMetricFilter::kFilter - : &LegacyBackendMetricFilter::kFilter) - .IfHasChannelArg(GRPC_ARG_SERVER_CALL_METRIC_RECORDING); + if (IsV3BackendMetricFilterEnabled()) { + builder->channel_init() + ->RegisterFilter(GRPC_SERVER_CHANNEL) + .IfHasChannelArg(GRPC_ARG_SERVER_CALL_METRIC_RECORDING); + } else { + builder->channel_init() + ->RegisterFilter(GRPC_SERVER_CHANNEL) + .IfHasChannelArg(GRPC_ARG_SERVER_CALL_METRIC_RECORDING); + } } } // namespace grpc_core diff --git a/src/core/ext/filters/channel_idle/channel_idle_filter.cc b/src/core/ext/filters/channel_idle/channel_idle_filter.cc index cd88ca58b3d..8e5fead77a2 100644 --- a/src/core/ext/filters/channel_idle/channel_idle_filter.cc +++ b/src/core/ext/filters/channel_idle/channel_idle_filter.cc @@ -296,13 +296,13 @@ const grpc_channel_filter MaxAgeFilter::kFilter = void RegisterChannelIdleFilters(CoreConfiguration::Builder* builder) { if (!IsV3ChannelIdleFiltersEnabled()) return; builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_CHANNEL, &ClientIdleFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_CHANNEL) .ExcludeFromMinimalStack() .If([](const ChannelArgs& channel_args) { return GetClientIdleTimeout(channel_args) != Duration::Infinity(); }); builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &MaxAgeFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .ExcludeFromMinimalStack() .If([](const ChannelArgs& channel_args) { return MaxAgeFilter::Config::FromChannelArgs(channel_args).enable(); diff --git a/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc b/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc index 23d97c9e2ff..8cb06f4b764 100644 --- a/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +++ b/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc @@ -302,13 +302,13 @@ const grpc_channel_filter LegacyMaxAgeFilter::kFilter = void RegisterLegacyChannelIdleFilters(CoreConfiguration::Builder* builder) { if (IsV3ChannelIdleFiltersEnabled()) return; builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_CHANNEL, &LegacyClientIdleFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_CHANNEL) .ExcludeFromMinimalStack() .If([](const ChannelArgs& channel_args) { return GetClientIdleTimeout(channel_args) != Duration::Infinity(); }); builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &LegacyMaxAgeFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .ExcludeFromMinimalStack() .If([](const ChannelArgs& channel_args) { return LegacyMaxAgeFilter::Config::FromChannelArgs(channel_args) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ae64ec93f00..8cec2474e55 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1928,8 +1928,7 @@ void RegisterGrpcLbPolicy(CoreConfiguration::Builder* builder) { builder->lb_policy_registry()->RegisterLoadBalancingPolicyFactory( std::make_unique()); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, - &ClientLoadReportingFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .IfChannelArg(GRPC_ARG_GRPCLB_ENABLE_LOAD_REPORTING_FILTER, false); } diff --git a/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc b/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc index 54169fcab06..e86e14246f4 100644 --- a/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +++ b/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc @@ -128,7 +128,7 @@ void RegisterServiceConfigChannelArgFilter( &kServiceConfigChannelArgFilter) .ExcludeFromMinimalStack() .IfHasChannelArg(GRPC_ARG_SERVICE_CONFIG) - .Before({&ClientMessageSizeFilter::kFilter}); + .Before(); } } // namespace grpc_core diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index a48c9554e41..973079e4db2 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -75,14 +75,13 @@ bool NeedsClientAuthorityFilter(const ChannelArgs& args) { void RegisterClientAuthorityFilter(CoreConfiguration::Builder* builder) { builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, &ClientAuthorityFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .If(NeedsClientAuthorityFilter) - .Before({&ClientAuthFilter::kFilter}); + .Before(); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, - &ClientAuthorityFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) .If(NeedsClientAuthorityFilter) - .Before({&ClientAuthFilter::kFilter}); + .Before(); } } // namespace grpc_core diff --git a/src/core/ext/filters/http/http_filters_plugin.cc b/src/core/ext/filters/http/http_filters_plugin.cc index b8099c45c2f..52706560c75 100644 --- a/src/core/ext/filters/http/http_filters_plugin.cc +++ b/src/core/ext/filters/http/http_filters_plugin.cc @@ -42,47 +42,49 @@ bool IsBuildingHttpLikeTransport(const ChannelArgs& args) { void RegisterHttpFilters(CoreConfiguration::Builder* builder) { if (IsV3CompressionFilterEnabled()) { builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, - &ClientCompressionFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter}); + .After() + .After(); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, - &ClientCompressionFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter}); + .After() + .After(); builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerCompressionFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&HttpServerFilter::kFilter, &ServerMessageSizeFilter::kFilter}); + .After() + .After(); } else { builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, - &LegacyClientCompressionFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter}); + .After() + .After(); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, - &LegacyClientCompressionFilter::kFilter) + ->RegisterFilter( + GRPC_CLIENT_DIRECT_CHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter}); + .After() + .After(); builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, - &LegacyServerCompressionFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&HttpServerFilter::kFilter, &ServerMessageSizeFilter::kFilter}); + .After() + .After(); } builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, &HttpClientFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&ClientMessageSizeFilter::kFilter}); + .After(); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, &HttpClientFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&ClientMessageSizeFilter::kFilter}); + .After(); builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &HttpServerFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .If(IsBuildingHttpLikeTransport) - .After({&ServerMessageSizeFilter::kFilter}); + .After(); } } // namespace grpc_core diff --git a/src/core/ext/filters/logging/logging_filter.cc b/src/core/ext/filters/logging/logging_filter.cc index 85e4871a086..0774e95c232 100644 --- a/src/core/ext/filters/logging/logging_filter.cc +++ b/src/core/ext/filters/logging/logging_filter.cc @@ -536,11 +536,11 @@ void RegisterLoggingFilter(LoggingSink* sink) { g_logging_sink = sink; CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) { builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerLoggingFilter::kFilter) + ->RegisterFilter(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, &ClientLoggingFilter::kFilter) + ->RegisterFilter(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/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 9cfc00474c4..ac010d40e1a 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -240,12 +240,10 @@ bool HasMessageSizeLimits(const ChannelArgs& channel_args) { void RegisterMessageSizeFilter(CoreConfiguration::Builder* builder) { MessageSizeParser::Register(builder); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, - &ClientMessageSizeFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .ExcludeFromMinimalStack(); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, - &ClientMessageSizeFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) .ExcludeFromMinimalStack() .If(HasMessageSizeLimits) // TODO(ctiller): ordering constraint is here to match the ordering that @@ -253,7 +251,7 @@ void RegisterMessageSizeFilter(CoreConfiguration::Builder* builder) { // filters from first principles. .Before({&grpc_client_deadline_filter}); builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerMessageSizeFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .ExcludeFromMinimalStack() .If(HasMessageSizeLimits) // TODO(ctiller): ordering constraint is here to match the ordering that diff --git a/src/core/lib/channel/server_call_tracer_filter.cc b/src/core/lib/channel/server_call_tracer_filter.cc index c2450a97d4c..2858d4ca0ad 100644 --- a/src/core/lib/channel/server_call_tracer_filter.cc +++ b/src/core/lib/channel/server_call_tracer_filter.cc @@ -104,8 +104,8 @@ absl::StatusOr ServerCallTracerFilter::Create( } // namespace void RegisterServerCallTracerFilter(CoreConfiguration::Builder* builder) { - builder->channel_init()->RegisterFilter(GRPC_SERVER_CHANNEL, - &ServerCallTracerFilter::kFilter); + builder->channel_init()->RegisterFilter( + GRPC_SERVER_CHANNEL); } } // namespace grpc_core diff --git a/src/core/lib/surface/builtins.cc b/src/core/lib/surface/builtins.cc index 189eb79072b..303fbb4dadc 100644 --- a/src/core/lib/surface/builtins.cc +++ b/src/core/lib/surface/builtins.cc @@ -27,7 +27,7 @@ namespace grpc_core { void RegisterBuiltins(CoreConfiguration::Builder* builder) { RegisterServerCallTracerFilter(builder); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_LAME_CHANNEL, &LameClientFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_LAME_CHANNEL) .Terminal(); builder->channel_init() ->RegisterFilter(GRPC_SERVER_CHANNEL, &Server::kServerTopFilter) diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index 12a441f0c40..344fe2c4dbb 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -87,11 +87,30 @@ class ChannelInit { // Ensure that this filter is placed *after* the filters listed here. // By Build() time all filters listed here must also be registered against // the same channel stack type as this registration. + template + FilterRegistration& After() { + return After({&Filter::kFilter}); + } + // Ensure that this filter is placed *before* the filters listed here. + // By Build() time all filters listed here must also be registered against + // the same channel stack type as this registration. + template + FilterRegistration& Before() { + return Before({&Filter::kFilter}); + } + + // Ensure that this filter is placed *after* the filters listed here. + // By Build() time all filters listed here must also be registered against + // the same channel stack type as this registration. + // TODO(ctiller): remove in favor of the version that does not mention + // grpc_channel_filter FilterRegistration& After( std::initializer_list filters); // Ensure that this filter is placed *before* the filters listed here. // By Build() time all filters listed here must also be registered against // the same channel stack type as this registration. + // TODO(ctiller): remove in favor of the version that does not mention + // grpc_channel_filter FilterRegistration& Before( std::initializer_list filters); // Add a predicate for this filters inclusion. @@ -145,9 +164,16 @@ class ChannelInit { // This occurs first during channel build time. // The FilterRegistration methods can be called to declaratively define // 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, SourceLocation registration_source = {}); + template + FilterRegistration& RegisterFilter( + grpc_channel_stack_type type, SourceLocation registration_source = {}) { + return RegisterFilter(type, &Filter::kFilter, registration_source); + } // Register a post processor for the builder. // These run after the main graph has been placed into the builder. diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index cf11feaf491..2c2b566cd46 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -67,25 +67,26 @@ 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, &ClientAuthFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, &ClientAuthFilter::kFilter) + ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) .IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR); if (IsV3ServerAuthFilterEnabled()) { builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerAuthFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .IfHasChannelArg(GRPC_SERVER_CREDENTIALS_ARG); } else { builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL, &LegacyServerAuthFilter::kFilter) + ->RegisterFilter(GRPC_SERVER_CHANNEL) .IfHasChannelArg(GRPC_SERVER_CREDENTIALS_ARG); } builder->channel_init() ->RegisterFilter(GRPC_SERVER_CHANNEL, &GrpcServerAuthzFilter::kFilterVtable) .IfHasChannelArg(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER) - .After({&ServerAuthFilter::kFilter, &LegacyServerAuthFilter::kFilter}); + .After() + .After(); } } // namespace grpc_core diff --git a/test/core/end2end/tests/http2_stats.cc b/test/core/end2end/tests/http2_stats.cc index d2fc0ea560c..5986039e421 100644 --- a/test/core/end2end/tests/http2_stats.cc +++ b/test/core/end2end/tests/http2_stats.cc @@ -214,8 +214,8 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) { g_client_call_ended_notify = new Notification(); g_server_call_ended_notify = new Notification(); CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) { - builder->channel_init()->RegisterFilter(GRPC_CLIENT_CHANNEL, - &FakeClientFilter::kFilter); + builder->channel_init()->RegisterFilter( + GRPC_CLIENT_CHANNEL); }); ServerCallTracerFactory::RegisterGlobal(new FakeServerCallTracerFactory); From c112dd7054189af77760d19b9198be0236a21065 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 5 Jan 2024 09:53:58 -0800 Subject: [PATCH 06/27] [server] Make pending queue timeout configurable (#35459) Help out with b/314162143 Closes #35459 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35459 from ctiller:config-timeout daa00917bcefab1a833145c827219a31bdce8095 PiperOrigin-RevId: 596019307 --- include/grpc/impl/channel_arg_names.h | 6 ++++++ src/core/lib/surface/server.cc | 6 +++++- src/core/lib/surface/server.h | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/grpc/impl/channel_arg_names.h b/include/grpc/impl/channel_arg_names.h index 534300f22c2..b42bf7026ef 100644 --- a/include/grpc/impl/channel_arg_names.h +++ b/include/grpc/impl/channel_arg_names.h @@ -106,6 +106,12 @@ */ #define GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS \ "grpc.http2.min_ping_interval_without_data_ms" +/** Maximum time to allow a request to be: + (1) received by the server, but + (2) not requested by a RequestCall (in the completion queue based API) + before the request is cancelled */ +#define GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS \ + "grpc.server_max_unrequested_time_in_server" /** Channel arg to override the http2 :scheme header */ #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" /** How many pings can the client send before needing to send a diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 249dca33497..44b541a8593 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -829,7 +829,11 @@ RefCountedPtr CreateChannelzNode( Server::Server(const ChannelArgs& args) : channel_args_(args), channelz_node_(CreateChannelzNode(args)), - server_call_tracer_factory_(ServerCallTracerFactory::Get(args)) {} + server_call_tracer_factory_(ServerCallTracerFactory::Get(args)), + max_time_in_pending_queue_(Duration::Seconds( + channel_args_ + .GetInt(GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS) + .value_or(30))) {} Server::~Server() { // Remove the cq pollsets from the config_fetcher. diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 83d5bc6a8d3..11ec7c68a45 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -489,7 +489,7 @@ class Server : public InternallyRefCounted, 0, channel_args_.GetInt(GRPC_ARG_SERVER_MAX_PENDING_REQUESTS_HARD_LIMIT) .value_or(3000)))}; - Duration max_time_in_pending_queue_{Duration::Seconds(30)}; + const Duration max_time_in_pending_queue_; absl::BitGen bitgen_ ABSL_GUARDED_BY(mu_call_); std::list channels_; From 2694f87c2385f52931cb2830adaa713d546db2ca Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 5 Jan 2024 15:00:34 -0800 Subject: [PATCH 07/27] [channel] Remove test only feature (#35465) It's not clear to me that this one unit test of very marginal importance warrants 8 bytes per channel. Closes #35465 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35465 from ctiller:we-dont-need-this-really e7ee62ccb25fda20bc4a88ddca9c90a411f11971 PiperOrigin-RevId: 596091614 --- include/grpcpp/test/channel_test_peer.h | 1 - src/core/lib/surface/channel.cc | 1 - src/core/lib/surface/channel.h | 6 ------ src/cpp/client/channel_test_peer.cc | 5 ----- test/cpp/end2end/end2end_test.cc | 2 -- 5 files changed, 15 deletions(-) diff --git a/include/grpcpp/test/channel_test_peer.h b/include/grpcpp/test/channel_test_peer.h index b180b8feda1..f4aad2a03b5 100644 --- a/include/grpcpp/test/channel_test_peer.h +++ b/include/grpcpp/test/channel_test_peer.h @@ -32,7 +32,6 @@ class ChannelTestPeer { /// Provide the gRPC Core channel grpc_channel* channel() const { return channel_->c_channel_; } int registered_calls() const; - int registration_attempts() const; private: Channel* channel_; // not owned diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index ca8927fc7e3..17d36b50e9a 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -376,7 +376,6 @@ namespace grpc_core { RegisteredCall* Channel::RegisterCall(const char* method, const char* host) { MutexLock lock(®istration_table_.mu); - registration_table_.method_registration_attempts++; auto key = std::make_pair(std::string(host != nullptr ? host : ""), std::string(method != nullptr ? method : "")); auto rc_posn = registration_table_.map.find(key); diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 2efe91fbfc2..f6e4f7ed932 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -103,7 +103,6 @@ struct CallRegistrationTable { // C++ or other wrapped language Channel that registered these calls). std::map, RegisteredCall> map ABSL_GUARDED_BY(mu); - int method_registration_attempts ABSL_GUARDED_BY(mu) = 0; }; class Channel : public RefCounted, @@ -150,11 +149,6 @@ class Channel : public RefCounted, return registration_table_.map.size(); } - int TestOnlyRegistrationAttempts() { - MutexLock lock(®istration_table_.mu); - return registration_table_.method_registration_attempts; - } - grpc_event_engine::experimental::EventEngine* event_engine() const { return channel_stack_->EventEngine(); } diff --git a/src/cpp/client/channel_test_peer.cc b/src/cpp/client/channel_test_peer.cc index e8b2f72c058..f694a749d16 100644 --- a/src/cpp/client/channel_test_peer.cc +++ b/src/cpp/client/channel_test_peer.cc @@ -29,10 +29,5 @@ int ChannelTestPeer::registered_calls() const { ->TestOnlyRegisteredCalls(); } -int ChannelTestPeer::registration_attempts() const { - return grpc_core::Channel::FromC(channel_->c_channel_) - ->TestOnlyRegistrationAttempts(); -} - } // namespace testing } // namespace grpc diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 7fc2d33132a..40964abe03f 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -862,12 +862,10 @@ TEST_P(End2endTest, ManyStubs) { ResetStub(); ChannelTestPeer peer(channel_.get()); int registered_calls_pre = peer.registered_calls(); - int registration_attempts_pre = peer.registration_attempts(); for (int i = 0; i < 1000; ++i) { grpc::testing::EchoTestService::NewStub(channel_); } EXPECT_EQ(peer.registered_calls(), registered_calls_pre); - EXPECT_GT(peer.registration_attempts(), registration_attempts_pre); } TEST_P(End2endTest, EmptyBinaryMetadata) { From 8d0c4b757788b8b15c28ccf44e4b2c27cb8bdda9 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Fri, 5 Jan 2024 16:03:44 -0800 Subject: [PATCH 08/27] Avoid warnings due to trailing backslash (#35464) I appreciate the elegance of using `\` and `/` to create ASCII art, but trailing backslashes in a `//` comment generates a lot of warnings with some compilers: ``` INFO: From Compiling src/core/lib/channel/promise_based_filter.cc: In file included from external/com_github_grpc_grpc/src/core/lib/surface/server.h:48, from external/com_github_grpc_grpc/src/core/lib/surface/call.h:53, from external/com_github_grpc_grpc/src/core/lib/channel/promise_based_filter.h:65, from external/com_github_grpc_grpc/src/core/lib/channel/promise_based_filter.cc:17: external/com_github_grpc_grpc/src/core/lib/channel/call_tracer.h:47:1: warning: multi-line comment [-Wcomment] 47 | // / \ | ^ external/com_github_grpc_grpc/src/core/lib/channel/call_tracer.h:49:1: warning: multi-line comment [-Wcomment] 49 | // / \ | ^ ``` Closes #35464 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35464 from coryan:coryan-patch-1 18a7f6b8e658aec2df29d88e8a1cbee8ef1b1129 PiperOrigin-RevId: 596103770 --- src/core/lib/channel/call_tracer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/channel/call_tracer.h b/src/core/lib/channel/call_tracer.h index e821cfcb5f8..78fd7fbb369 100644 --- a/src/core/lib/channel/call_tracer.h +++ b/src/core/lib/channel/call_tracer.h @@ -44,9 +44,9 @@ namespace grpc_core { // The interface hierarchy is as follows - // CallTracerAnnotationInterface -// / \ +// | | // ClientCallTracer CallTracerInterface -// / \ +// | | // CallAttemptTracer ServerCallTracer // The base class for all tracer implementations. From b5c5b7a264add29d33e5b374c875da5d80c2e60a Mon Sep 17 00:00:00 2001 From: Gregory Cooke Date: Fri, 5 Jan 2024 19:39:12 -0800 Subject: [PATCH 09/27] [OpenSSL] Disable another test (#35461) This accidentally slipped through the cracks on https://github.com/grpc/grpc/pull/35444 Closes #35461 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35461 from gtcooke94:fix_ossl102_part2 c8b526cefab6f9ea4faa3b27747ccd8d4a9ab361 PiperOrigin-RevId: 596135991 --- test/cpp/end2end/tls_credentials_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/cpp/end2end/tls_credentials_test.cc b/test/cpp/end2end/tls_credentials_test.cc index 24f83d6f898..1c3fd837082 100644 --- a/test/cpp/end2end/tls_credentials_test.cc +++ b/test/cpp/end2end/tls_credentials_test.cc @@ -129,6 +129,8 @@ void DoRpc(const std::string& server_addr, EXPECT_EQ(response.message(), kMessage); } +// TODO(gregorycooke) - failing with OpenSSL1.0.2 +#if OPENSSL_VERSION_NUMBER >= 0x10100000 // How do we test that skipping server certificate verification works as // expected? Give the server credentials that chain up to a custom CA (that does // not belong to the default or OS trust store), do not configure the client to @@ -149,6 +151,7 @@ TEST_F(TlsCredentialsTest, SkipServerCertificateVerification) { DoRpc(server_addr_, tls_options); } +#endif // OPENSSL_VERSION_NUMBER >= 0x10100000 } // namespace } // namespace testing From 86522af60db2678ed522c95b7dbb9e86c7a5481c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 8 Jan 2024 09:43:16 -0800 Subject: [PATCH 10/27] [chaotic-good] Client & server transport (#35400) Adapts work from https://github.com/grpc/grpc/pull/34728 and previous changes from @nanahpang, implements new v3 filter/transport interface, and brings up the core of the chaotic good transport. The next change will bring a more complete test suite (for this and inproc). Closes #35400 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35400 from ctiller:v3-server 737ca5431a44b3ac8d65eb738fd11179ecca197b PiperOrigin-RevId: 596621152 --- CMakeLists.txt | 52 ++ build_autogenerated.yaml | 44 +- .../grpc/event_engine/internal/slice_cast.h | 12 + include/grpc/event_engine/slice.h | 5 + src/core/BUILD | 85 +++ .../chaotic_good/chaotic_good_transport.cc | 19 + .../chaotic_good/chaotic_good_transport.h | 111 ++++ .../chaotic_good/client_transport.cc | 331 ++++++---- .../transport/chaotic_good/client_transport.h | 202 ++---- src/core/ext/transport/chaotic_good/frame.cc | 171 +++-- src/core/ext/transport/chaotic_good/frame.h | 83 ++- .../transport/chaotic_good/frame_header.cc | 11 +- .../ext/transport/chaotic_good/frame_header.h | 2 +- .../chaotic_good/server_transport.cc | 332 ++++++++++ .../transport/chaotic_good/server_transport.h | 145 ++++ .../ext/transport/inproc/inproc_transport.cc | 8 +- src/core/lib/gprpp/debug_location.h | 9 + src/core/lib/promise/detail/status.h | 45 +- .../promise/event_engine_wakeup_scheduler.h | 4 +- src/core/lib/promise/if.h | 4 + src/core/lib/promise/inter_activity_pipe.h | 10 +- src/core/lib/promise/mpsc.h | 22 +- src/core/lib/promise/status_flag.h | 24 + src/core/lib/promise/try_join.h | 6 +- src/core/lib/promise/try_seq.h | 29 +- src/core/lib/resource_quota/arena.h | 4 +- src/core/lib/slice/slice_buffer.h | 3 + src/core/lib/surface/call.cc | 13 +- src/core/lib/surface/call.h | 3 +- src/core/lib/surface/server.cc | 23 +- src/core/lib/surface/server.h | 6 +- src/core/lib/transport/promise_endpoint.h | 36 +- src/core/lib/transport/transport.cc | 14 +- src/core/lib/transport/transport.h | 151 ++++- test/core/promise/mpsc_test.cc | 2 + test/core/transport/chaotic_good/BUILD | 86 ++- .../client_transport_error_test.cc | 549 ++++++++-------- .../chaotic_good/client_transport_test.cc | 618 ++++++------------ .../transport/chaotic_good/frame_fuzzer.cc | 63 +- .../transport/chaotic_good/frame_fuzzer.proto | 23 + .../frame_fuzzer_corpus/5072496117219328 | Bin 26 -> 0 bytes .../frame_fuzzer_corpus/5691448031772672 | Bin 51 -> 0 bytes ...h-05c704327d21af2cc914de40e9d90d06f16ca0eb | Bin 74 -> 0 bytes ...h-5015de8c7cafb0b0ebbbfd28c29aedd5dbfdc03a | Bin 66 -> 0 bytes ...h-5a34978de8de6889ce913947a77f43f7cdea854c | Bin 180 -> 0 bytes ...h-608f798a51077a8cdc45b11f335c079a81339fbe | Bin 166 -> 0 bytes ...h-6a002cb46eac21af4ab6fd74b61ff3ce26d96dff | Bin 161 -> 0 bytes ...h-7732ddd35a4deb8b7c9e462aaf8680986755e540 | Bin 79 -> 0 bytes ...h-c171e98ebfe8b6485f9a4bea0b9cdfe683776675 | Bin 70 -> 0 bytes .../chaotic_good/frame_fuzzer_corpus/empty | 1 + .../chaotic_good/frame_header_test.cc | 12 +- .../core/transport/chaotic_good/frame_test.cc | 31 +- .../chaotic_good/mock_promise_endpoint.cc | 89 +++ .../chaotic_good/mock_promise_endpoint.h | 77 +++ .../chaotic_good/server_transport_test.cc | 198 ++++++ .../transport/chaotic_good/transport_test.cc | 60 ++ .../transport/chaotic_good/transport_test.h | 67 ++ test/core/transport/promise_endpoint_test.cc | 40 +- tools/run_tests/generated/tests.json | 24 + 59 files changed, 2716 insertions(+), 1243 deletions(-) create mode 100644 src/core/ext/transport/chaotic_good/chaotic_good_transport.cc create mode 100644 src/core/ext/transport/chaotic_good/chaotic_good_transport.h create mode 100644 src/core/ext/transport/chaotic_good/server_transport.cc create mode 100644 src/core/ext/transport/chaotic_good/server_transport.h create mode 100644 test/core/transport/chaotic_good/frame_fuzzer.proto delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/5072496117219328 delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/5691448031772672 delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-05c704327d21af2cc914de40e9d90d06f16ca0eb delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-5015de8c7cafb0b0ebbbfd28c29aedd5dbfdc03a delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-5a34978de8de6889ce913947a77f43f7cdea854c delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-608f798a51077a8cdc45b11f335c079a81339fbe delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-6a002cb46eac21af4ab6fd74b61ff3ce26d96dff delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-7732ddd35a4deb8b7c9e462aaf8680986755e540 delete mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-c171e98ebfe8b6485f9a4bea0b9cdfe683776675 create mode 100644 test/core/transport/chaotic_good/frame_fuzzer_corpus/empty create mode 100644 test/core/transport/chaotic_good/mock_promise_endpoint.cc create mode 100644 test/core/transport/chaotic_good/mock_promise_endpoint.h create mode 100644 test/core/transport/chaotic_good/server_transport_test.cc create mode 100644 test/core/transport/chaotic_good/transport_test.cc create mode 100644 test/core/transport/chaotic_good/transport_test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 17d1a7410a8..5d178f90137 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1326,6 +1326,7 @@ if(gRPC_BUILD_TESTS) endif() add_dependencies(buildtests_cxx server_streaming_test) add_dependencies(buildtests_cxx server_test) + add_dependencies(buildtests_cxx server_transport_test) add_dependencies(buildtests_cxx service_config_end2end_test) add_dependencies(buildtests_cxx service_config_test) add_dependencies(buildtests_cxx settings_timeout_test) @@ -9533,6 +9534,7 @@ add_executable(client_transport_error_test ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h + src/core/ext/transport/chaotic_good/chaotic_good_transport.cc src/core/ext/transport/chaotic_good/client_transport.cc src/core/ext/transport/chaotic_good/frame.cc src/core/ext/transport/chaotic_good/frame_header.cc @@ -9563,6 +9565,7 @@ target_include_directories(client_transport_error_test target_link_libraries(client_transport_error_test ${_gRPC_ALLTARGETS_LIBRARIES} gtest + grpc_unsecure ${_gRPC_PROTOBUF_LIBRARIES} grpc_test_util ) @@ -9576,12 +9579,15 @@ add_executable(client_transport_test ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h + src/core/ext/transport/chaotic_good/chaotic_good_transport.cc src/core/ext/transport/chaotic_good/client_transport.cc src/core/ext/transport/chaotic_good/frame.cc src/core/ext/transport/chaotic_good/frame_header.cc src/core/lib/transport/promise_endpoint.cc test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc test/core/transport/chaotic_good/client_transport_test.cc + test/core/transport/chaotic_good/mock_promise_endpoint.cc + test/core/transport/chaotic_good/transport_test.cc ) target_compile_features(client_transport_test PUBLIC cxx_std_14) target_include_directories(client_transport_test @@ -22380,6 +22386,52 @@ target_link_libraries(server_test ) +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_transport_test + ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.cc + ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h + ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h + src/core/ext/transport/chaotic_good/chaotic_good_transport.cc + src/core/ext/transport/chaotic_good/frame.cc + src/core/ext/transport/chaotic_good/frame_header.cc + src/core/ext/transport/chaotic_good/server_transport.cc + src/core/lib/transport/promise_endpoint.cc + test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc + test/core/transport/chaotic_good/mock_promise_endpoint.cc + test/core/transport/chaotic_good/server_transport_test.cc + test/core/transport/chaotic_good/transport_test.cc +) +target_compile_features(server_transport_test PUBLIC cxx_std_14) +target_include_directories(server_transport_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(server_transport_test + ${_gRPC_ALLTARGETS_LIBRARIES} + gtest + ${_gRPC_PROTOBUF_LIBRARIES} + grpc_test_util +) + + endif() if(gRPC_BUILD_TESTS) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index b1492ba7068..46cd87ce1d7 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -7646,6 +7646,7 @@ targets: build: test language: c++ headers: + - src/core/ext/transport/chaotic_good/chaotic_good_transport.h - src/core/ext/transport/chaotic_good/client_transport.h - src/core/ext/transport/chaotic_good/frame.h - src/core/ext/transport/chaotic_good/frame_header.h @@ -7658,6 +7659,7 @@ targets: - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h src: - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto + - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - src/core/ext/transport/chaotic_good/client_transport.cc - src/core/ext/transport/chaotic_good/frame.cc - src/core/ext/transport/chaotic_good/frame_header.cc @@ -7666,6 +7668,7 @@ targets: - test/core/transport/chaotic_good/client_transport_error_test.cc deps: - gtest + - grpc_unsecure - protobuf - grpc_test_util uses_polling: false @@ -7674,24 +7677,29 @@ targets: build: test language: c++ headers: + - src/core/ext/transport/chaotic_good/chaotic_good_transport.h - src/core/ext/transport/chaotic_good/client_transport.h - src/core/ext/transport/chaotic_good/frame.h - src/core/ext/transport/chaotic_good/frame_header.h - src/core/lib/promise/event_engine_wakeup_scheduler.h - src/core/lib/promise/inter_activity_pipe.h - - src/core/lib/promise/join.h - src/core/lib/promise/mpsc.h - src/core/lib/promise/wait_set.h - src/core/lib/transport/promise_endpoint.h - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h + - test/core/transport/chaotic_good/mock_promise_endpoint.h + - test/core/transport/chaotic_good/transport_test.h src: - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto + - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - src/core/ext/transport/chaotic_good/client_transport.cc - src/core/ext/transport/chaotic_good/frame.cc - src/core/ext/transport/chaotic_good/frame_header.cc - src/core/lib/transport/promise_endpoint.cc - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - test/core/transport/chaotic_good/client_transport_test.cc + - test/core/transport/chaotic_good/mock_promise_endpoint.cc + - test/core/transport/chaotic_good/transport_test.cc deps: - gtest - protobuf @@ -15568,6 +15576,40 @@ targets: deps: - gtest - grpc_test_util +- name: server_transport_test + gtest: true + build: test + language: c++ + headers: + - src/core/ext/transport/chaotic_good/chaotic_good_transport.h + - src/core/ext/transport/chaotic_good/frame.h + - src/core/ext/transport/chaotic_good/frame_header.h + - src/core/ext/transport/chaotic_good/server_transport.h + - src/core/lib/promise/event_engine_wakeup_scheduler.h + - src/core/lib/promise/inter_activity_pipe.h + - src/core/lib/promise/mpsc.h + - src/core/lib/promise/switch.h + - src/core/lib/promise/wait_set.h + - src/core/lib/transport/promise_endpoint.h + - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h + - test/core/transport/chaotic_good/mock_promise_endpoint.h + - test/core/transport/chaotic_good/transport_test.h + src: + - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto + - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc + - src/core/ext/transport/chaotic_good/frame.cc + - src/core/ext/transport/chaotic_good/frame_header.cc + - src/core/ext/transport/chaotic_good/server_transport.cc + - src/core/lib/transport/promise_endpoint.cc + - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc + - test/core/transport/chaotic_good/mock_promise_endpoint.cc + - test/core/transport/chaotic_good/server_transport_test.cc + - test/core/transport/chaotic_good/transport_test.cc + deps: + - gtest + - protobuf + - grpc_test_util + uses_polling: false - name: service_config_end2end_test gtest: true build: test diff --git a/include/grpc/event_engine/internal/slice_cast.h b/include/grpc/event_engine/internal/slice_cast.h index 8bcca60a24a..3f9593464cf 100644 --- a/include/grpc/event_engine/internal/slice_cast.h +++ b/include/grpc/event_engine/internal/slice_cast.h @@ -60,6 +60,18 @@ Result& SliceCast(T& value, SliceCastable = {}) { return reinterpret_cast(value); } +// Cast to `Result&&` from `T&&` without any runtime checks. +// This is only valid if `sizeof(Result) == sizeof(T)`, and if `Result`, `T` are +// opted in as compatible via `SliceCastable`. +template +Result&& SliceCast(T&& value, SliceCastable = {}) { + // Insist upon sizes being equal to catch mismatches. + // We assume if sizes are opted in and sizes are equal then yes, these two + // types are expected to be layout compatible and actually appear to be. + static_assert(sizeof(Result) == sizeof(T), "size mismatch"); + return reinterpret_cast(value); +} + } // namespace internal } // namespace experimental } // namespace grpc_event_engine diff --git a/include/grpc/event_engine/slice.h b/include/grpc/event_engine/slice.h index 8d49f391600..ce7693f6489 100644 --- a/include/grpc/event_engine/slice.h +++ b/include/grpc/event_engine/slice.h @@ -169,6 +169,11 @@ struct CopyConstructors { return Out(grpc_slice_from_copied_buffer(p, len)); } + static Out FromCopiedBuffer(const uint8_t* p, size_t len) { + return Out( + grpc_slice_from_copied_buffer(reinterpret_cast(p), len)); + } + template static Out FromCopiedBuffer(const Buffer& buffer) { return FromCopiedBuffer(reinterpret_cast(buffer.data()), diff --git a/src/core/BUILD b/src/core/BUILD index fcb11452d18..8ee2f308b86 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -6213,6 +6213,7 @@ grpc_cc_library( "bitset", "chaotic_good_frame_header", "context", + "match", "no_destruct", "slice", "slice_buffer", @@ -6368,6 +6369,29 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "chaotic_good_transport", + srcs = [ + "ext/transport/chaotic_good/chaotic_good_transport.cc", + ], + hdrs = [ + "ext/transport/chaotic_good/chaotic_good_transport.h", + ], + external_deps = ["absl/random"], + language = "c++", + deps = [ + "chaotic_good_frame", + "chaotic_good_frame_header", + "grpc_promise_endpoint", + "if", + "try_join", + "try_seq", + "//:gpr_platform", + "//:hpack_encoder", + "//:promise", + ], +) + grpc_cc_library( name = "chaotic_good_client_transport", srcs = [ @@ -6378,6 +6402,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/container:flat_hash_map", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -6388,9 +6413,11 @@ grpc_cc_library( language = "c++", deps = [ "activity", + "all_ok", "arena", "chaotic_good_frame", "chaotic_good_frame_header", + "chaotic_good_transport", "context", "event_engine_wakeup_scheduler", "for_each", @@ -6398,6 +6425,7 @@ grpc_cc_library( "if", "inter_activity_pipe", "loop", + "map", "match", "memory_quota", "mpsc", @@ -6414,6 +6442,63 @@ grpc_cc_library( "//:grpc_base", "//:hpack_encoder", "//:hpack_parser", + "//:promise", + "//:ref_counted_ptr", + ], +) + +grpc_cc_library( + name = "chaotic_good_server_transport", + srcs = [ + "ext/transport/chaotic_good/server_transport.cc", + ], + hdrs = [ + "ext/transport/chaotic_good/server_transport.h", + ], + external_deps = [ + "absl/base:core_headers", + "absl/container:flat_hash_map", + "absl/functional:any_invocable", + "absl/random", + "absl/random:bit_gen_ref", + "absl/status", + "absl/status:statusor", + "absl/types:optional", + "absl/types:variant", + ], + language = "c++", + deps = [ + "1999", + "activity", + "arena", + "chaotic_good_frame", + "chaotic_good_frame_header", + "chaotic_good_transport", + "context", + "default_event_engine", + "event_engine_wakeup_scheduler", + "for_each", + "grpc_promise_endpoint", + "if", + "inter_activity_pipe", + "loop", + "memory_quota", + "mpsc", + "pipe", + "poll", + "resource_quota", + "seq", + "slice", + "slice_buffer", + "switch", + "try_join", + "try_seq", + "//:exec_ctx", + "//:gpr", + "//:gpr_platform", + "//:grpc_base", + "//:hpack_encoder", + "//:hpack_parser", "//:ref_counted_ptr", ], ) diff --git a/src/core/ext/transport/chaotic_good/chaotic_good_transport.cc b/src/core/ext/transport/chaotic_good/chaotic_good_transport.cc new file mode 100644 index 00000000000..163f994d35f --- /dev/null +++ b/src/core/ext/transport/chaotic_good/chaotic_good_transport.cc @@ -0,0 +1,19 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/core/ext/transport/chaotic_good/chaotic_good_transport.h" + +namespace grpc_core {} // namespace grpc_core diff --git a/src/core/ext/transport/chaotic_good/chaotic_good_transport.h b/src/core/ext/transport/chaotic_good/chaotic_good_transport.h new file mode 100644 index 00000000000..1096486bbea --- /dev/null +++ b/src/core/ext/transport/chaotic_good/chaotic_good_transport.h @@ -0,0 +1,111 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_CHAOTIC_GOOD_TRANSPORT_H +#define GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_CHAOTIC_GOOD_TRANSPORT_H + +#include + +#include "absl/random/random.h" + +#include "src/core/ext/transport/chaotic_good/frame.h" +#include "src/core/ext/transport/chaotic_good/frame_header.h" +#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" +#include "src/core/lib/promise/if.h" +#include "src/core/lib/promise/promise.h" +#include "src/core/lib/promise/try_join.h" +#include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/transport/promise_endpoint.h" + +namespace grpc_core { +namespace chaotic_good { + +class ChaoticGoodTransport { + public: + ChaoticGoodTransport(std::unique_ptr control_endpoint, + std::unique_ptr data_endpoint) + : control_endpoint_(std::move(control_endpoint)), + data_endpoint_(std::move(data_endpoint)) {} + + auto WriteFrame(const FrameInterface& frame) { + auto buffers = frame.Serialize(&encoder_); + return TryJoin( + control_endpoint_->Write(std::move(buffers.control)), + data_endpoint_->Write(std::move(buffers.data))); + } + + // Read frame header and payloads for control and data portions of one frame. + // Resolves to StatusOr>. + auto ReadFrameBytes() { + return TrySeq( + control_endpoint_->ReadSlice(FrameHeader::frame_header_size_), + [this](Slice read_buffer) { + auto frame_header = + FrameHeader::Parse(reinterpret_cast( + GRPC_SLICE_START_PTR(read_buffer.c_slice()))); + // Read header and trailers from control endpoint. + // Read message padding and message from data endpoint. + return If( + frame_header.ok(), + [this, &frame_header] { + const uint32_t message_padding = std::exchange( + last_message_padding_, frame_header->message_padding); + const uint32_t message_length = frame_header->message_length; + return Map( + TryJoin( + control_endpoint_->Read(frame_header->GetFrameLength()), + TrySeq(data_endpoint_->Read(message_padding), + [this, message_length]() { + return data_endpoint_->Read(message_length); + })), + [frame_header = *frame_header]( + absl::StatusOr> + buffers) + -> absl::StatusOr> { + if (!buffers.ok()) return buffers.status(); + return std::tuple( + frame_header, + BufferPair{std::move(std::get<0>(*buffers)), + std::move(std::get<1>(*buffers))}); + }); + }, + [&frame_header]() + -> absl::StatusOr> { + return frame_header.status(); + }); + }); + } + + absl::Status DeserializeFrame(FrameHeader header, BufferPair buffers, + Arena* arena, FrameInterface& frame) { + return frame.Deserialize(&parser_, header, bitgen_, arena, + std::move(buffers)); + } + + // Skip a frame, but correctly handle any hpack state updates. + void SkipFrame(FrameHeader, BufferPair) { Crash("not implemented"); } + + private: + const std::unique_ptr control_endpoint_; + const std::unique_ptr data_endpoint_; + uint32_t last_message_padding_ = 0; + HPackCompressor encoder_; + HPackParser parser_; + absl::BitGen bitgen_; +}; + +} // namespace chaotic_good +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_CHAOTIC_GOOD_TRANSPORT_H diff --git a/src/core/ext/transport/chaotic_good/client_transport.cc b/src/core/ext/transport/chaotic_good/client_transport.cc index 24f30687182..d4075bcad1b 100644 --- a/src/core/ext/transport/chaotic_good/client_transport.cc +++ b/src/core/ext/transport/chaotic_good/client_transport.cc @@ -17,9 +17,11 @@ #include "src/core/ext/transport/chaotic_good/client_transport.h" #include +#include #include #include #include +#include #include "absl/random/bit_gen_ref.h" #include "absl/random/random.h" @@ -36,9 +38,13 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/promise/activity.h" +#include "src/core/lib/promise/all_ok.h" #include "src/core/lib/promise/event_engine_wakeup_scheduler.h" #include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/map.h" +#include "src/core/lib/promise/promise.h" #include "src/core/lib/promise/try_join.h" +#include "src/core/lib/promise/try_seq.h" #include "src/core/lib/resource_quota/arena.h" #include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/slice/slice.h" @@ -49,59 +55,15 @@ namespace grpc_core { namespace chaotic_good { -ClientTransport::ClientTransport( - std::unique_ptr control_endpoint, - std::unique_ptr data_endpoint, - std::shared_ptr event_engine) - : outgoing_frames_(MpscReceiver(4)), - control_endpoint_(std::move(control_endpoint)), - data_endpoint_(std::move(data_endpoint)), - control_endpoint_write_buffer_(SliceBuffer()), - data_endpoint_write_buffer_(SliceBuffer()), - hpack_compressor_(std::make_unique()), - hpack_parser_(std::make_unique()), - memory_allocator_( - ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator( - "client_transport")), - arena_(MakeScopedArena(1024, &memory_allocator_)), - context_(arena_.get()), - event_engine_(event_engine) { - auto write_loop = Loop([this] { +auto ChaoticGoodClientTransport::TransportWriteLoop() { + return Loop([this] { return TrySeq( // Get next outgoing frame. - this->outgoing_frames_.Next(), - // Construct data buffers that will be sent to the endpoints. + outgoing_frames_.Next(), + // Serialize and write it out. [this](ClientFrame client_frame) { - MatchMutable( - &client_frame, - [this](ClientFragmentFrame* frame) mutable { - control_endpoint_write_buffer_.Append( - frame->Serialize(hpack_compressor_.get())); - if (frame->message != nullptr) { - std::string message_padding(frame->message_padding, '0'); - Slice slice(grpc_slice_from_cpp_string(message_padding)); - // Append message padding to data_endpoint_buffer. - data_endpoint_write_buffer_.Append(std::move(slice)); - // Append message payload to data_endpoint_buffer. - frame->message->payload()->MoveFirstNBytesIntoSliceBuffer( - frame->message->payload()->Length(), - data_endpoint_write_buffer_); - } - }, - [this](CancelFrame* frame) mutable { - control_endpoint_write_buffer_.Append( - frame->Serialize(hpack_compressor_.get())); - }); - return absl::OkStatus(); + return transport_.WriteFrame(GetFrameInterface(client_frame)); }, - // Write buffers to corresponding endpoints concurrently. - [this]() { - return TryJoin( - control_endpoint_->Write( - std::move(control_endpoint_write_buffer_)), - data_endpoint_->Write(std::move(data_endpoint_write_buffer_))); - }, - // Finish writes to difference endpoints and continue the loop. []() -> LoopCtl { // The write failures will be caught in TrySeq and exit loop. // Therefore, only need to return Continue() in the last lambda @@ -109,78 +71,215 @@ ClientTransport::ClientTransport( return Continue(); }); }); - writer_ = MakeActivity( - // Continuously write next outgoing frames to promise endpoints. - std::move(write_loop), EventEngineWakeupScheduler(event_engine_), - [this](absl::Status status) { - if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) { - this->AbortWithError(); - } +} + +absl::optional ChaoticGoodClientTransport::LookupStream( + uint32_t stream_id) { + MutexLock lock(&mu_); + auto it = stream_map_.find(stream_id); + if (it == stream_map_.end()) { + return absl::nullopt; + } + return it->second; +} + +auto ChaoticGoodClientTransport::PushFrameIntoCall(ServerFragmentFrame frame, + CallHandler call_handler) { + auto& headers = frame.headers; + return TrySeq( + If( + headers != nullptr, + [call_handler, &headers]() mutable { + return call_handler.PushServerInitialMetadata(std::move(headers)); + }, + []() -> StatusFlag { return Success{}; }), + [call_handler, message = std::move(frame.message)]() mutable { + return If( + message.has_value(), + [&call_handler, &message]() mutable { + return call_handler.PushMessage(std::move(message->message)); + }, + []() -> StatusFlag { return Success{}; }); }, - // Hold Arena in activity for GetContext usage. - arena_.get()); - auto read_loop = Loop([this] { + [call_handler, trailers = std::move(frame.trailers)]() mutable { + return If( + trailers != nullptr, + [&call_handler, &trailers]() mutable { + return call_handler.PushServerTrailingMetadata( + std::move(trailers)); + }, + []() -> StatusFlag { return Success{}; }); + }); +} + +auto ChaoticGoodClientTransport::TransportReadLoop() { + return Loop([this] { return TrySeq( - // Read frame header from control endpoint. - // TODO(ladynana): remove memcpy in ReadSlice. - this->control_endpoint_->ReadSlice(FrameHeader::frame_header_size_), - // Read different parts of the server frame from control/data endpoints - // based on frame header. - [this](Slice read_buffer) mutable { - frame_header_ = std::make_shared( - FrameHeader::Parse( - reinterpret_cast( - GRPC_SLICE_START_PTR(read_buffer.c_slice()))) - .value()); - // Read header and trailers from control endpoint. - // Read message padding and message from data endpoint. - return TryJoin( - control_endpoint_->Read(frame_header_->GetFrameLength()), - data_endpoint_->Read(frame_header_->message_padding + - frame_header_->message_length)); - }, - // Construct and send the server frame to corresponding stream. - [this](std::tuple ret) mutable { - control_endpoint_read_buffer_ = std::move(std::get<0>(ret)); - // Discard message padding and only keep message in data read buffer. - std::get<1>(ret).MoveLastNBytesIntoSliceBuffer( - frame_header_->message_length, data_endpoint_read_buffer_); - ServerFragmentFrame frame; - // Initialized to get this_cpu() info in global_stat(). - ExecCtx exec_ctx; - // Deserialize frame from read buffer. - absl::BitGen bitgen; - auto status = frame.Deserialize(hpack_parser_.get(), *frame_header_, - absl::BitGenRef(bitgen), - control_endpoint_read_buffer_); - GPR_ASSERT(status.ok()); - // Move message into frame. - frame.message = arena_->MakePooled( - std::move(data_endpoint_read_buffer_), 0); - MutexLock lock(&mu_); - const uint32_t stream_id = frame_header_->stream_id; - return stream_map_[stream_id]->Push(ServerFrame(std::move(frame))); - }, - // Check if send frame to corresponding stream successfully. - [](bool ret) -> LoopCtl { - if (ret) { - // Send incoming frames successfully. - return Continue(); - } else { - return absl::InternalError("Send incoming frames failed."); + transport_.ReadFrameBytes(), + [](std::tuple frame_bytes) + -> absl::StatusOr> { + const auto& frame_header = std::get<0>(frame_bytes); + if (frame_header.type != FrameType::kFragment) { + return absl::InternalError( + absl::StrCat("Expected fragment frame, got ", + static_cast(frame_header.type))); } - }); + return frame_bytes; + }, + [this](std::tuple frame_bytes) { + const auto& frame_header = std::get<0>(frame_bytes); + auto& buffers = std::get<1>(frame_bytes); + absl::optional call_handler = + LookupStream(frame_header.stream_id); + ServerFragmentFrame frame; + absl::Status deserialize_status; + if (call_handler.has_value()) { + deserialize_status = transport_.DeserializeFrame( + frame_header, std::move(buffers), call_handler->arena(), frame); + } else { + // Stream not found, skip the frame. + transport_.SkipFrame(frame_header, std::move(buffers)); + deserialize_status = absl::OkStatus(); + } + return If( + deserialize_status.ok() && call_handler.has_value(), + [this, &frame, &call_handler]() { + return call_handler->SpawnWaitable( + "push-frame", [this, call_handler = *call_handler, + frame = std::move(frame)]() mutable { + return Map(call_handler.CancelIfFails(PushFrameIntoCall( + std::move(frame), call_handler)), + [](StatusFlag f) { + return StatusCast(f); + }); + }); + }, + [&deserialize_status]() -> absl::Status { + // Stream not found, nothing to do. + return std::move(deserialize_status); + }); + }, + []() -> LoopCtl { return Continue{}; }); }); - reader_ = MakeActivity( - // Continuously read next incoming frames from promise endpoints. - std::move(read_loop), EventEngineWakeupScheduler(event_engine_), - [this](absl::Status status) { - if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) { - this->AbortWithError(); - } +} + +auto ChaoticGoodClientTransport::OnTransportActivityDone() { + return [this](absl::Status status) { + if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) { + this->AbortWithError(); + } + }; +} + +ChaoticGoodClientTransport::ChaoticGoodClientTransport( + std::unique_ptr control_endpoint, + std::unique_ptr data_endpoint, + std::shared_ptr event_engine) + : outgoing_frames_(4), + transport_(std::move(control_endpoint), std::move(data_endpoint)), + writer_{ + MakeActivity( + // Continuously write next outgoing frames to promise endpoints. + TransportWriteLoop(), EventEngineWakeupScheduler(event_engine), + OnTransportActivityDone()), }, - // Hold Arena in activity for GetContext usage. - arena_.get()); + reader_{MakeActivity( + // Continuously read next incoming frames from promise endpoints. + TransportReadLoop(), EventEngineWakeupScheduler(event_engine), + OnTransportActivityDone())} {} + +ChaoticGoodClientTransport::~ChaoticGoodClientTransport() { + if (writer_ != nullptr) { + writer_.reset(); + } + if (reader_ != nullptr) { + reader_.reset(); + } +} + +void ChaoticGoodClientTransport::AbortWithError() { + // Mark transport as unavailable when the endpoint write/read failed. + // Close all the available pipes. + outgoing_frames_.MarkClosed(); + ReleasableMutexLock lock(&mu_); + StreamMap stream_map = std::move(stream_map_); + stream_map_.clear(); + lock.Release(); + for (const auto& pair : stream_map) { + auto call_handler = pair.second; + call_handler.SpawnInfallible("cancel", [call_handler]() mutable { + call_handler.Cancel(ServerMetadataFromStatus( + absl::UnavailableError("Transport closed."))); + return Empty{}; + }); + } +} + +uint32_t ChaoticGoodClientTransport::MakeStream(CallHandler call_handler) { + ReleasableMutexLock lock(&mu_); + const uint32_t stream_id = next_stream_id_++; + stream_map_.emplace(stream_id, call_handler); + lock.Release(); + call_handler.OnDone([this, stream_id]() { + MutexLock lock(&mu_); + stream_map_.erase(stream_id); + }); + return stream_id; +} + +auto ChaoticGoodClientTransport::CallOutboundLoop(uint32_t stream_id, + CallHandler call_handler) { + auto send_fragment = [stream_id, + outgoing_frames = outgoing_frames_.MakeSender()]( + ClientFragmentFrame frame) mutable { + frame.stream_id = stream_id; + return Map(outgoing_frames.Send(std::move(frame)), + [](bool success) -> absl::Status { + if (!success) { + // Failed to send outgoing frame. + return absl::UnavailableError("Transport closed."); + } + return absl::OkStatus(); + }); + }; + return TrySeq( + // Wait for initial metadata then send it out. + call_handler.PullClientInitialMetadata(), + [send_fragment](ClientMetadataHandle md) mutable { + ClientFragmentFrame frame; + frame.headers = std::move(md); + return send_fragment(std::move(frame)); + }, + // Continuously send client frame with client to server messages. + ForEach(OutgoingMessages(call_handler), + [send_fragment, + aligned_bytes = aligned_bytes_](MessageHandle message) mutable { + ClientFragmentFrame frame; + // Construct frame header (flags, header_length and + // trailer_length will be added in serialization). + const uint32_t message_length = message->payload()->Length(); + const uint32_t padding = + message_length % aligned_bytes == 0 + ? 0 + : aligned_bytes - message_length % aligned_bytes; + GPR_ASSERT((message_length + padding) % aligned_bytes == 0); + frame.message = FragmentMessage(std::move(message), padding, + message_length); + return send_fragment(std::move(frame)); + }), + [send_fragment]() mutable { + ClientFragmentFrame frame; + frame.end_of_stream = true; + return send_fragment(std::move(frame)); + }); +} + +void ChaoticGoodClientTransport::StartCall(CallHandler call_handler) { + // At this point, the connection is set up. + // Start sending data frames. + call_handler.SpawnGuarded("outbound_loop", [this, call_handler]() mutable { + return CallOutboundLoop(MakeStream(call_handler), call_handler); + }); } } // namespace chaotic_good diff --git a/src/core/ext/transport/chaotic_good/client_transport.h b/src/core/ext/transport/chaotic_good/client_transport.h index 23ecdbfe84a..b8d515f9896 100644 --- a/src/core/ext/transport/chaotic_good/client_transport.h +++ b/src/core/ext/transport/chaotic_good/client_transport.h @@ -20,6 +20,7 @@ #include #include +#include #include // IWYU pragma: keep #include #include @@ -28,6 +29,8 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_map.h" +#include "absl/random/random.h" #include "absl/status/status.h" #include "absl/types/optional.h" #include "absl/types/variant.h" @@ -35,6 +38,7 @@ #include #include +#include "src/core/ext/transport/chaotic_good/chaotic_good_transport.h" #include "src/core/ext/transport/chaotic_good/frame.h" #include "src/core/ext/transport/chaotic_good/frame_header.h" #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" @@ -61,178 +65,56 @@ namespace grpc_core { namespace chaotic_good { -class ClientTransport { +class ChaoticGoodClientTransport final : public Transport, + public ClientTransport { public: - ClientTransport(std::unique_ptr control_endpoint, - std::unique_ptr data_endpoint, - std::shared_ptr - event_engine); - ~ClientTransport() { - if (writer_ != nullptr) { - writer_.reset(); - } - if (reader_ != nullptr) { - reader_.reset(); - } - } - void AbortWithError() { - // Mark transport as unavailable when the endpoint write/read failed. - // Close all the available pipes. - if (!outgoing_frames_.IsClosed()) { - outgoing_frames_.MarkClosed(); - } - MutexLock lock(&mu_); - for (const auto& pair : stream_map_) { - if (!pair.second->IsClose()) { - pair.second->MarkClose(); - } - } - } - auto AddStream(CallArgs call_args) { - // At this point, the connection is set up. - // Start sending data frames. - uint32_t stream_id; - InterActivityPipe pipe_server_frames; - { - MutexLock lock(&mu_); - stream_id = next_stream_id_++; - stream_map_.insert( - std::pair::Sender>>( - stream_id, std::make_shared::Sender>( - std::move(pipe_server_frames.sender)))); - } - return TrySeq( - TryJoin( - // Continuously send client frame with client to server messages. - ForEach(std::move(*call_args.client_to_server_messages), - [stream_id, initial_frame = true, - client_initial_metadata = - std::move(call_args.client_initial_metadata), - outgoing_frames = outgoing_frames_.MakeSender(), - this](MessageHandle result) mutable { - ClientFragmentFrame frame; - // Construct frame header (flags, header_length and - // trailer_length will be added in serialization). - uint32_t message_length = result->payload()->Length(); - frame.stream_id = stream_id; - frame.message_padding = message_length % aligned_bytes; - frame.message = std::move(result); - if (initial_frame) { - // Send initial frame with client intial metadata. - frame.headers = std::move(client_initial_metadata); - initial_frame = false; - } - return TrySeq( - outgoing_frames.Send(ClientFrame(std::move(frame))), - [](bool success) -> absl::Status { - if (!success) { - // TODO(ladynana): propagate the actual error - // message from EventEngine. - return absl::UnavailableError( - "Transport closed due to endpoint write/read " - "failed."); - } - return absl::OkStatus(); - }); - }), - // Continuously receive server frames from endpoints and save - // results to call_args. - Loop([server_initial_metadata = call_args.server_initial_metadata, - server_to_client_messages = - call_args.server_to_client_messages, - receiver = std::move(pipe_server_frames.receiver)]() mutable { - return TrySeq( - // Receive incoming server frame. - receiver.Next(), - // Save incomming frame results to call_args. - [server_initial_metadata, server_to_client_messages]( - absl::optional server_frame) mutable { - bool transport_closed = false; - ServerFragmentFrame frame; - if (!server_frame.has_value()) { - // Incoming server frame pipe is closed, which only - // happens when transport is aborted. - transport_closed = true; - } else { - frame = std::move( - absl::get(*server_frame)); - }; - bool has_headers = (frame.headers != nullptr); - bool has_message = (frame.message != nullptr); - bool has_trailers = (frame.trailers != nullptr); - return TrySeq( - If((!transport_closed) && has_headers, - [server_initial_metadata, - headers = std::move(frame.headers)]() mutable { - return server_initial_metadata->Push( - std::move(headers)); - }, - [] { return false; }), - If((!transport_closed) && has_message, - [server_to_client_messages, - message = std::move(frame.message)]() mutable { - return server_to_client_messages->Push( - std::move(message)); - }, - [] { return false; }), - If((!transport_closed) && has_trailers, - [trailers = std::move(frame.trailers)]() mutable - -> LoopCtl { - return std::move(trailers); - }, - [transport_closed]() - -> LoopCtl { - if (transport_closed) { - // TODO(ladynana): propagate the actual error - // message from EventEngine. - return ServerMetadataFromStatus( - absl::UnavailableError( - "Transport closed due to endpoint " - "write/read failed.")); - } - return Continue(); - })); - }); - })), - [](std::tuple ret) { - return std::move(std::get<1>(ret)); - }); - } + ChaoticGoodClientTransport( + std::unique_ptr control_endpoint, + std::unique_ptr data_endpoint, + std::shared_ptr + event_engine); + ~ChaoticGoodClientTransport() override; + + FilterStackTransport* filter_stack_transport() override { return nullptr; } + ClientTransport* client_transport() override { return this; } + ServerTransport* server_transport() override { return nullptr; } + absl::string_view GetTransportName() const override { return "chaotic_good"; } + void SetPollset(grpc_stream*, grpc_pollset*) override {} + void SetPollsetSet(grpc_stream*, grpc_pollset_set*) override {} + void PerformOp(grpc_transport_op*) override { Crash("unimplemented"); } + grpc_endpoint* GetEndpoint() override { return nullptr; } + void Orphan() override { delete this; } + + void StartCall(CallHandler call_handler) override; + void AbortWithError(); private: + // Queue size of each stream pipe is set to 2, so that for each stream read it + // will queue at most 2 frames. + static const size_t kServerFrameQueueSize = 2; + using StreamMap = absl::flat_hash_map; + + uint32_t MakeStream(CallHandler call_handler); + absl::optional LookupStream(uint32_t stream_id); + auto CallOutboundLoop(uint32_t stream_id, CallHandler call_handler); + auto OnTransportActivityDone(); + auto TransportWriteLoop(); + auto TransportReadLoop(); + // Push one frame into a call + auto PushFrameIntoCall(ServerFragmentFrame frame, CallHandler call_handler); + // Max buffer is set to 4, so that for stream writes each time it will queue // at most 2 frames. MpscReceiver outgoing_frames_; - // Queue size of each stream pipe is set to 2, so that for each stream read it - // will queue at most 2 frames. - static const size_t server_frame_queue_size_ = 2; + ChaoticGoodTransport transport_; // Assigned aligned bytes from setting frame. - size_t aligned_bytes = 64; + size_t aligned_bytes_ = 64; Mutex mu_; uint32_t next_stream_id_ ABSL_GUARDED_BY(mu_) = 1; // Map of stream incoming server frames, key is stream_id. - std::map::Sender>> - stream_map_ ABSL_GUARDED_BY(mu_); + StreamMap stream_map_ ABSL_GUARDED_BY(mu_); ActivityPtr writer_; ActivityPtr reader_; - std::unique_ptr control_endpoint_; - std::unique_ptr data_endpoint_; - SliceBuffer control_endpoint_write_buffer_; - SliceBuffer data_endpoint_write_buffer_; - SliceBuffer control_endpoint_read_buffer_; - SliceBuffer data_endpoint_read_buffer_; - std::unique_ptr hpack_compressor_; - std::unique_ptr hpack_parser_; - std::shared_ptr frame_header_; - MemoryAllocator memory_allocator_; - ScopedArenaPtr arena_; - promise_detail::Context context_; - // Use to synchronize writer_ and reader_ activity with outside activities; - std::shared_ptr event_engine_; }; } // namespace chaotic_good diff --git a/src/core/ext/transport/chaotic_good/frame.cc b/src/core/ext/transport/chaotic_good/frame.cc index f49fa4c4f3b..d2c0b3a4fc0 100644 --- a/src/core/ext/transport/chaotic_good/frame.cc +++ b/src/core/ext/transport/chaotic_good/frame.cc @@ -40,6 +40,10 @@ namespace grpc_core { namespace chaotic_good { +namespace { +const uint8_t kZeros[64] = {}; +} + namespace { const NoDestruct kZeroSlice{[] { // Frame header size is fixed to 24 bytes. @@ -50,53 +54,65 @@ const NoDestruct kZeroSlice{[] { class FrameSerializer { public: - explicit FrameSerializer(FrameType frame_type, uint32_t stream_id, - uint32_t message_padding) { - output_.AppendIndexed(kZeroSlice->Copy()); + explicit FrameSerializer(FrameType frame_type, uint32_t stream_id) { + output_.control.AppendIndexed(kZeroSlice->Copy()); header_.type = frame_type; header_.stream_id = stream_id; - header_.message_padding = message_padding; header_.flags.SetAll(false); } + // If called, must be called before AddTrailers, Finish. SliceBuffer& AddHeaders() { header_.flags.set(0); - return output_; - } - // If called, must be called before Finish. - SliceBuffer& AddTrailers() { - header_.flags.set(1); - header_.header_length = output_.Length() - FrameHeader::frame_header_size_; - return output_; + return output_.control; } - SliceBuffer Finish() { + void AddMessage(const FragmentMessage& msg) { + header_.flags.set(1); + header_.message_length = msg.length; + header_.message_padding = msg.padding; + output_.data = msg.message->payload()->Copy(); + if (msg.padding != 0) { + output_.data.Append(Slice::FromStaticBuffer(kZeros, msg.padding)); + } + } + + // If called, must be called before Finish. + SliceBuffer& AddTrailers() { + header_.flags.set(2); + header_.header_length = + output_.control.Length() - FrameHeader::frame_header_size_; + return output_.control; + } + + BufferPair Finish() { // Calculate frame header_length or trailer_length if available. - if (header_.flags.is_set(1)) { + if (header_.flags.is_set(2)) { // Header length is already known in AddTrailers(). - header_.trailer_length = output_.Length() - header_.header_length - + header_.trailer_length = output_.control.Length() - + header_.header_length - FrameHeader::frame_header_size_; } else { if (header_.flags.is_set(0)) { // Calculate frame header length in Finish() since AddTrailers() isn't // called. header_.header_length = - output_.Length() - FrameHeader::frame_header_size_; + output_.control.Length() - FrameHeader::frame_header_size_; } } header_.Serialize( - GRPC_SLICE_START_PTR(output_.c_slice_buffer()->slices[0])); + GRPC_SLICE_START_PTR(output_.control.c_slice_buffer()->slices[0])); return std::move(output_); } private: FrameHeader header_; - SliceBuffer output_; + BufferPair output_; }; class FrameDeserializer { public: - FrameDeserializer(const FrameHeader& header, SliceBuffer& input) + FrameDeserializer(const FrameHeader& header, BufferPair& input) : header_(header), input_(input) {} const FrameHeader& header() const { return header_; } // If called, must be called before ReceiveTrailers, Finish. @@ -118,28 +134,27 @@ class FrameDeserializer { private: absl::StatusOr Take(uint32_t length) { if (length == 0) return SliceBuffer{}; - if (input_.Length() < length) { + if (input_.control.Length() < length) { return absl::InvalidArgumentError( "Frame too short (insufficient payload)"); } SliceBuffer out; - input_.MoveFirstNBytesIntoSliceBuffer(length, out); + input_.control.MoveFirstNBytesIntoSliceBuffer(length, out); return std::move(out); } FrameHeader header_; - SliceBuffer& input_; + BufferPair& input_; }; template absl::StatusOr> ReadMetadata( HPackParser* parser, absl::StatusOr maybe_slices, - uint32_t stream_id, bool is_header, bool is_client, - absl::BitGenRef bitsrc) { + uint32_t stream_id, bool is_header, bool is_client, absl::BitGenRef bitsrc, + Arena* arena) { if (!maybe_slices.ok()) return maybe_slices.status(); auto& slices = *maybe_slices; - auto arena = GetContext(); GPR_ASSERT(arena != nullptr); - Arena::PoolPtr metadata = arena->MakePooled(arena); + Arena::PoolPtr metadata = Arena::MakePooled(arena); parser->BeginFrame( metadata.get(), std::numeric_limits::max(), std::numeric_limits::max(), @@ -161,20 +176,23 @@ absl::StatusOr> ReadMetadata( } // namespace absl::Status SettingsFrame::Deserialize(HPackParser*, const FrameHeader& header, - absl::BitGenRef, - SliceBuffer& slice_buffer) { + absl::BitGenRef, Arena*, + BufferPair buffers) { if (header.type != FrameType::kSettings) { return absl::InvalidArgumentError("Expected settings frame"); } if (header.flags.any()) { return absl::InvalidArgumentError("Unexpected flags"); } - FrameDeserializer deserializer(header, slice_buffer); + if (buffers.data.Length() != 0) { + return absl::InvalidArgumentError("Unexpected data"); + } + FrameDeserializer deserializer(header, buffers); return deserializer.Finish(); } -SliceBuffer SettingsFrame::Serialize(HPackCompressor*) const { - FrameSerializer serializer(FrameType::kSettings, 0, 0); +BufferPair SettingsFrame::Serialize(HPackCompressor*) const { + FrameSerializer serializer(FrameType::kSettings, 0); return serializer.Finish(); } @@ -183,19 +201,20 @@ std::string SettingsFrame::ToString() const { return "SettingsFrame{}"; } absl::Status ClientFragmentFrame::Deserialize(HPackParser* parser, const FrameHeader& header, absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) { + Arena* arena, + BufferPair buffers) { if (header.stream_id == 0) { return absl::InvalidArgumentError("Expected non-zero stream id"); } stream_id = header.stream_id; - message_padding = header.message_padding; if (header.type != FrameType::kFragment) { return absl::InvalidArgumentError("Expected fragment frame"); } - FrameDeserializer deserializer(header, slice_buffer); + FrameDeserializer deserializer(header, buffers); if (header.flags.is_set(0)) { auto r = ReadMetadata(parser, deserializer.ReceiveHeaders(), - header.stream_id, true, true, bitsrc); + header.stream_id, true, true, bitsrc, + arena); if (!r.ok()) return r.status(); if (r.value() != nullptr) { headers = std::move(r.value()); @@ -205,8 +224,17 @@ absl::Status ClientFragmentFrame::Deserialize(HPackParser* parser, "Unexpected non-zero header length", header.header_length)); } if (header.flags.is_set(1)) { + message = + FragmentMessage{Arena::MakePooled(std::move(buffers.data), 0), + header.message_padding, header.message_length}; + } else if (buffers.data.Length() != 0) { + return absl::InvalidArgumentError(absl::StrCat( + "Unexpected non-zero message length ", buffers.data.Length())); + } + if (header.flags.is_set(2)) { if (header.trailer_length != 0) { - return absl::InvalidArgumentError("Unexpected trailer length"); + return absl::InvalidArgumentError( + absl::StrCat("Unexpected trailer length ", header.trailer_length)); } end_of_stream = true; } else { @@ -215,42 +243,53 @@ absl::Status ClientFragmentFrame::Deserialize(HPackParser* parser, return deserializer.Finish(); } -SliceBuffer ClientFragmentFrame::Serialize(HPackCompressor* encoder) const { +BufferPair ClientFragmentFrame::Serialize(HPackCompressor* encoder) const { GPR_ASSERT(stream_id != 0); - FrameSerializer serializer(FrameType::kFragment, stream_id, message_padding); + FrameSerializer serializer(FrameType::kFragment, stream_id); if (headers.get() != nullptr) { encoder->EncodeRawHeaders(*headers.get(), serializer.AddHeaders()); } + if (message.has_value()) { + serializer.AddMessage(message.value()); + } if (end_of_stream) { serializer.AddTrailers(); } return serializer.Finish(); } +std::string FragmentMessage::ToString() const { + std::string out = + absl::StrCat("FragmentMessage{length=", length, ", padding=", padding); + if (message.get() != nullptr) { + absl::StrAppend(&out, ", message=", message->DebugString().c_str()); + } + absl::StrAppend(&out, "}"); + return out; +} + std::string ClientFragmentFrame::ToString() const { return absl::StrCat( "ClientFragmentFrame{stream_id=", stream_id, ", headers=", headers.get() != nullptr ? headers->DebugString().c_str() : "nullptr", - ", message=", - message.get() != nullptr ? message->DebugString().c_str() : "nullptr", - ", message_padding=", message_padding, ", end_of_stream=", end_of_stream, - "}"); + ", message=", message.has_value() ? message->ToString().c_str() : "none", + ", end_of_stream=", end_of_stream, "}"); } absl::Status ServerFragmentFrame::Deserialize(HPackParser* parser, const FrameHeader& header, absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) { + Arena* arena, + BufferPair buffers) { if (header.stream_id == 0) { return absl::InvalidArgumentError("Expected non-zero stream id"); } stream_id = header.stream_id; - message_padding = header.message_padding; - FrameDeserializer deserializer(header, slice_buffer); + FrameDeserializer deserializer(header, buffers); if (header.flags.is_set(0)) { - auto r = - ReadMetadata(parser, deserializer.ReceiveHeaders(), - header.stream_id, true, false, bitsrc); + auto r = ReadMetadata(parser, deserializer.ReceiveHeaders(), + header.stream_id, true, false, bitsrc, + arena); if (!r.ok()) return r.status(); if (r.value() != nullptr) { headers = std::move(r.value()); @@ -260,9 +299,16 @@ absl::Status ServerFragmentFrame::Deserialize(HPackParser* parser, "Unexpected non-zero header length", header.header_length)); } if (header.flags.is_set(1)) { - auto r = - ReadMetadata(parser, deserializer.ReceiveTrailers(), - header.stream_id, false, false, bitsrc); + message.emplace(Arena::MakePooled(std::move(buffers.data), 0), + header.message_padding, header.message_length); + } else if (buffers.data.Length() != 0) { + return absl::InvalidArgumentError(absl::StrCat( + "Unexpected non-zero message length", buffers.data.Length())); + } + if (header.flags.is_set(2)) { + auto r = ReadMetadata( + parser, deserializer.ReceiveTrailers(), header.stream_id, false, false, + bitsrc, arena); if (!r.ok()) return r.status(); if (r.value() != nullptr) { trailers = std::move(r.value()); @@ -274,12 +320,15 @@ absl::Status ServerFragmentFrame::Deserialize(HPackParser* parser, return deserializer.Finish(); } -SliceBuffer ServerFragmentFrame::Serialize(HPackCompressor* encoder) const { +BufferPair ServerFragmentFrame::Serialize(HPackCompressor* encoder) const { GPR_ASSERT(stream_id != 0); - FrameSerializer serializer(FrameType::kFragment, stream_id, message_padding); + FrameSerializer serializer(FrameType::kFragment, stream_id); if (headers.get() != nullptr) { encoder->EncodeRawHeaders(*headers.get(), serializer.AddHeaders()); } + if (message.has_value()) { + serializer.AddMessage(message.value()); + } if (trailers.get() != nullptr) { encoder->EncodeRawHeaders(*trailers.get(), serializer.AddTrailers()); } @@ -290,16 +339,15 @@ std::string ServerFragmentFrame::ToString() const { return absl::StrCat( "ServerFragmentFrame{stream_id=", stream_id, ", headers=", headers.get() != nullptr ? headers->DebugString().c_str() : "nullptr", - ", message=", - message.get() != nullptr ? message->DebugString().c_str() : "nullptr", - ", message_padding=", message_padding, ", trailers=", + ", message=", message.has_value() ? message->ToString().c_str() : "none", + ", trailers=", trailers.get() != nullptr ? trailers->DebugString().c_str() : "nullptr", "}"); } absl::Status CancelFrame::Deserialize(HPackParser*, const FrameHeader& header, - absl::BitGenRef, - SliceBuffer& slice_buffer) { + absl::BitGenRef, Arena*, + BufferPair buffers) { if (header.type != FrameType::kCancel) { return absl::InvalidArgumentError("Expected cancel frame"); } @@ -309,14 +357,17 @@ absl::Status CancelFrame::Deserialize(HPackParser*, const FrameHeader& header, if (header.stream_id == 0) { return absl::InvalidArgumentError("Expected non-zero stream id"); } - FrameDeserializer deserializer(header, slice_buffer); + if (buffers.data.Length() != 0) { + return absl::InvalidArgumentError("Unexpected data"); + } + FrameDeserializer deserializer(header, buffers); stream_id = header.stream_id; return deserializer.Finish(); } -SliceBuffer CancelFrame::Serialize(HPackCompressor*) const { +BufferPair CancelFrame::Serialize(HPackCompressor*) const { GPR_ASSERT(stream_id != 0); - FrameSerializer serializer(FrameType::kCancel, stream_id, 0); + FrameSerializer serializer(FrameType::kCancel, stream_id); return serializer.Finish(); } diff --git a/src/core/ext/transport/chaotic_good/frame.h b/src/core/ext/transport/chaotic_good/frame.h index 529c89570c7..e7ccd6ee222 100644 --- a/src/core/ext/transport/chaotic_good/frame.h +++ b/src/core/ext/transport/chaotic_good/frame.h @@ -28,6 +28,7 @@ #include "src/core/ext/transport/chaotic_good/frame_header.h" #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" #include "src/core/ext/transport/chttp2/transport/hpack_parser.h" +#include "src/core/lib/gprpp/match.h" #include "src/core/lib/resource_quota/arena.h" #include "src/core/lib/slice/slice_buffer.h" #include "src/core/lib/transport/metadata_batch.h" @@ -36,20 +37,21 @@ namespace grpc_core { namespace chaotic_good { +struct BufferPair { + SliceBuffer control; + SliceBuffer data; +}; + class FrameInterface { public: virtual absl::Status Deserialize(HPackParser* parser, const FrameHeader& header, - absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) = 0; - virtual SliceBuffer Serialize(HPackCompressor* encoder) const = 0; + absl::BitGenRef bitsrc, Arena* arena, + BufferPair buffers) = 0; + virtual BufferPair Serialize(HPackCompressor* encoder) const = 0; virtual std::string ToString() const = 0; protected: - static bool EqVal(const Message& a, const Message& b) { - return a.payload()->JoinIntoString() == b.payload()->JoinIntoString() && - a.flags() == b.flags(); - } static bool EqVal(const grpc_metadata_batch& a, const grpc_metadata_batch& b) { return a.DebugString() == b.DebugString(); @@ -65,57 +67,75 @@ class FrameInterface { struct SettingsFrame final : public FrameInterface { absl::Status Deserialize(HPackParser* parser, const FrameHeader& header, - absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) override; - SliceBuffer Serialize(HPackCompressor* encoder) const override; + absl::BitGenRef bitsrc, Arena* arena, + BufferPair buffers) override; + BufferPair Serialize(HPackCompressor* encoder) const override; std::string ToString() const override; bool operator==(const SettingsFrame&) const { return true; } }; +struct FragmentMessage { + FragmentMessage(MessageHandle message, uint32_t padding, uint32_t length) + : message(std::move(message)), padding(padding), length(length) {} + + MessageHandle message; + uint32_t padding; + uint32_t length; + + std::string ToString() const; + + static bool EqVal(const Message& a, const Message& b) { + return a.payload()->JoinIntoString() == b.payload()->JoinIntoString() && + a.flags() == b.flags(); + } + + bool operator==(const FragmentMessage& other) const { + return EqVal(*message, *other.message) && length == other.length; + } +}; + struct ClientFragmentFrame final : public FrameInterface { absl::Status Deserialize(HPackParser* parser, const FrameHeader& header, - absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) override; - SliceBuffer Serialize(HPackCompressor* encoder) const override; + absl::BitGenRef bitsrc, Arena* arena, + BufferPair buffers) override; + BufferPair Serialize(HPackCompressor* encoder) const override; std::string ToString() const override; uint32_t stream_id; ClientMetadataHandle headers; - MessageHandle message; - uint32_t message_padding; + absl::optional message; bool end_of_stream = false; bool operator==(const ClientFragmentFrame& other) const { return stream_id == other.stream_id && EqHdl(headers, other.headers) && - end_of_stream == other.end_of_stream; + message == other.message && end_of_stream == other.end_of_stream; } }; struct ServerFragmentFrame final : public FrameInterface { absl::Status Deserialize(HPackParser* parser, const FrameHeader& header, - absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) override; - SliceBuffer Serialize(HPackCompressor* encoder) const override; + absl::BitGenRef bitsrc, Arena* arena, + BufferPair buffers) override; + BufferPair Serialize(HPackCompressor* encoder) const override; std::string ToString() const override; uint32_t stream_id; ServerMetadataHandle headers; - MessageHandle message; - uint32_t message_padding; + absl::optional message; ServerMetadataHandle trailers; bool operator==(const ServerFragmentFrame& other) const { return stream_id == other.stream_id && EqHdl(headers, other.headers) && - EqHdl(trailers, other.trailers); + message == other.message && EqHdl(trailers, other.trailers); } }; struct CancelFrame final : public FrameInterface { absl::Status Deserialize(HPackParser* parser, const FrameHeader& header, - absl::BitGenRef bitsrc, - SliceBuffer& slice_buffer) override; - SliceBuffer Serialize(HPackCompressor* encoder) const override; + absl::BitGenRef bitsrc, Arena* arena, + BufferPair buffers) override; + BufferPair Serialize(HPackCompressor* encoder) const override; std::string ToString() const override; uint32_t stream_id; @@ -128,6 +148,19 @@ struct CancelFrame final : public FrameInterface { using ClientFrame = absl::variant; using ServerFrame = absl::variant; +inline FrameInterface& GetFrameInterface(ClientFrame& frame) { + return MatchMutable( + &frame, + [](ClientFragmentFrame* frame) -> FrameInterface& { return *frame; }, + [](CancelFrame* frame) -> FrameInterface& { return *frame; }); +} + +inline FrameInterface& GetFrameInterface(ServerFrame& frame) { + return MatchMutable( + &frame, + [](ServerFragmentFrame* frame) -> FrameInterface& { return *frame; }); +} + } // namespace chaotic_good } // namespace grpc_core diff --git a/src/core/ext/transport/chaotic_good/frame_header.cc b/src/core/ext/transport/chaotic_good/frame_header.cc index e39d6a34b58..06f9d146e66 100644 --- a/src/core/ext/transport/chaotic_good/frame_header.cc +++ b/src/core/ext/transport/chaotic_good/frame_header.cc @@ -46,7 +46,6 @@ void FrameHeader::Serialize(uint8_t* data) const { WriteLittleEndianUint32( static_cast(type) | (flags.ToInt() << 8), data); if (flags.is_set(0)) GPR_ASSERT(header_length > 0); - if (flags.is_set(1)) GPR_ASSERT(trailer_length > 0); WriteLittleEndianUint32(stream_id, data + 4); WriteLittleEndianUint32(header_length, data + 8); WriteLittleEndianUint32(message_length, data + 12); @@ -60,8 +59,8 @@ absl::StatusOr FrameHeader::Parse(const uint8_t* data) { const uint32_t type_and_flags = ReadLittleEndianUint32(data); header.type = static_cast(type_and_flags & 0xff); const uint32_t flags = type_and_flags >> 8; - if (flags > 3) return absl::InvalidArgumentError("Invalid flags"); - header.flags = BitSet<2>::FromInt(flags); + if (flags > 7) return absl::InvalidArgumentError("Invalid flags"); + header.flags = BitSet<3>::FromInt(flags); header.stream_id = ReadLittleEndianUint32(data + 4); header.header_length = ReadLittleEndianUint32(data + 8); if (header.flags.is_set(0) && header.header_length <= 0) { @@ -70,11 +69,11 @@ absl::StatusOr FrameHeader::Parse(const uint8_t* data) { } header.message_length = ReadLittleEndianUint32(data + 12); header.message_padding = ReadLittleEndianUint32(data + 16); - header.trailer_length = ReadLittleEndianUint32(data + 20); - if (header.flags.is_set(1) && header.trailer_length <= 0) { + if (header.flags.is_set(1) && header.message_length <= 0) { return absl::InvalidArgumentError( - absl::StrCat("Invalid trailer length", header.trailer_length)); + absl::StrCat("Invalid message length: ", header.message_length)); } + header.trailer_length = ReadLittleEndianUint32(data + 20); return header; } diff --git a/src/core/ext/transport/chaotic_good/frame_header.h b/src/core/ext/transport/chaotic_good/frame_header.h index fa236ed3342..773b44f26e3 100644 --- a/src/core/ext/transport/chaotic_good/frame_header.h +++ b/src/core/ext/transport/chaotic_good/frame_header.h @@ -36,7 +36,7 @@ enum class FrameType : uint8_t { struct FrameHeader { FrameType type = FrameType::kCancel; - BitSet<2> flags; + BitSet<3> flags; uint32_t stream_id = 0; uint32_t header_length = 0; uint32_t message_length = 0; diff --git a/src/core/ext/transport/chaotic_good/server_transport.cc b/src/core/ext/transport/chaotic_good/server_transport.cc new file mode 100644 index 00000000000..3d4387ac949 --- /dev/null +++ b/src/core/ext/transport/chaotic_good/server_transport.cc @@ -0,0 +1,332 @@ +// Copyright 2022 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/core/ext/transport/chaotic_good/server_transport.h" + +#include +#include +#include + +#include "absl/random/bit_gen_ref.h" +#include "absl/random/random.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" + +#include +#include +#include + +#include "src/core/ext/transport/chaotic_good/frame.h" +#include "src/core/ext/transport/chaotic_good/frame_header.h" +#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/promise/activity.h" +#include "src/core/lib/promise/event_engine_wakeup_scheduler.h" +#include "src/core/lib/promise/for_each.h" +#include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/switch.h" +#include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/resource_quota/arena.h" +#include "src/core/lib/resource_quota/resource_quota.h" +#include "src/core/lib/slice/slice.h" +#include "src/core/lib/slice/slice_buffer.h" +#include "src/core/lib/transport/promise_endpoint.h" + +namespace grpc_core { +namespace chaotic_good { + +auto ChaoticGoodServerTransport::TransportWriteLoop() { + return Loop([this] { + return TrySeq( + // Get next outgoing frame. + outgoing_frames_.Next(), + // Serialize and write it out. + [this](ServerFrame client_frame) { + return transport_.WriteFrame(GetFrameInterface(client_frame)); + }, + []() -> LoopCtl { + // The write failures will be caught in TrySeq and exit loop. + // Therefore, only need to return Continue() in the last lambda + // function. + return Continue(); + }); + }); +} + +auto ChaoticGoodServerTransport::PushFragmentIntoCall( + CallInitiator call_initiator, ClientFragmentFrame frame) { + auto& headers = frame.headers; + return TrySeq( + If( + headers != nullptr, + [call_initiator, &headers]() mutable { + return call_initiator.PushClientInitialMetadata(std::move(headers)); + }, + []() -> StatusFlag { return Success{}; }), + [call_initiator, message = std::move(frame.message)]() mutable { + return If( + message.has_value(), + [&call_initiator, &message]() mutable { + return call_initiator.PushMessage(std::move(message->message)); + }, + []() -> StatusFlag { return Success{}; }); + }, + [call_initiator, + end_of_stream = frame.end_of_stream]() mutable -> StatusFlag { + if (end_of_stream) call_initiator.FinishSends(); + return Success{}; + }); +} + +auto ChaoticGoodServerTransport::MaybePushFragmentIntoCall( + absl::optional call_initiator, absl::Status error, + ClientFragmentFrame frame) { + return If( + call_initiator.has_value() && error.ok(), + [this, &call_initiator, &frame]() { + return Map( + call_initiator->SpawnWaitable( + "push-fragment", + [call_initiator, frame = std::move(frame), this]() mutable { + return call_initiator->CancelIfFails( + PushFragmentIntoCall(*call_initiator, std::move(frame))); + }), + [](StatusFlag status) { return StatusCast(status); }); + }, + [error = std::move(error)]() { return error; }); +} + +auto ChaoticGoodServerTransport::CallOutboundLoop( + uint32_t stream_id, CallInitiator call_initiator) { + auto send_fragment = [stream_id, + outgoing_frames = outgoing_frames_.MakeSender()]( + ServerFragmentFrame frame) mutable { + frame.stream_id = stream_id; + return Map(outgoing_frames.Send(std::move(frame)), + [](bool success) -> absl::Status { + if (!success) { + // Failed to send outgoing frame. + return absl::UnavailableError("Transport closed."); + } + return absl::OkStatus(); + }); + }; + return Seq( + TrySeq( + // Wait for initial metadata then send it out. + call_initiator.PullServerInitialMetadata(), + [send_fragment](ServerMetadataHandle md) mutable { + ServerFragmentFrame frame; + frame.headers = std::move(md); + return send_fragment(std::move(frame)); + }, + // Continuously send client frame with client to server messages. + ForEach(OutgoingMessages(call_initiator), + [send_fragment, aligned_bytes = aligned_bytes_]( + MessageHandle message) mutable { + ServerFragmentFrame frame; + // Construct frame header (flags, header_length and + // trailer_length will be added in serialization). + const uint32_t message_length = + message->payload()->Length(); + const uint32_t padding = + message_length % aligned_bytes == 0 + ? 0 + : aligned_bytes - message_length % aligned_bytes; + GPR_ASSERT((message_length + padding) % aligned_bytes == 0); + frame.message = FragmentMessage(std::move(message), padding, + message_length); + return send_fragment(std::move(frame)); + })), + call_initiator.PullServerTrailingMetadata(), + [send_fragment](ServerMetadataHandle md) mutable { + ServerFragmentFrame frame; + frame.trailers = std::move(md); + return send_fragment(std::move(frame)); + }); +} + +auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToNewCall( + FrameHeader frame_header, BufferPair buffers) { + ClientFragmentFrame fragment_frame; + ScopedArenaPtr arena(acceptor_->CreateArena()); + absl::Status status = transport_.DeserializeFrame( + frame_header, std::move(buffers), arena.get(), fragment_frame); + absl::optional call_initiator; + if (status.ok()) { + auto create_call_result = + acceptor_->CreateCall(*fragment_frame.headers, arena.release()); + if (create_call_result.ok()) { + call_initiator.emplace(std::move(*create_call_result)); + 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(); + } + } + return MaybePushFragmentIntoCall(std::move(call_initiator), std::move(status), + std::move(fragment_frame)); +} + +auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToExistingCall( + FrameHeader frame_header, BufferPair buffers) { + absl::optional call_initiator = + LookupStream(frame_header.stream_id); + Arena* arena = nullptr; + if (call_initiator.has_value()) arena = call_initiator->arena(); + ClientFragmentFrame fragment_frame; + absl::Status status = transport_.DeserializeFrame( + frame_header, std::move(buffers), arena, fragment_frame); + return MaybePushFragmentIntoCall(std::move(call_initiator), std::move(status), + std::move(fragment_frame)); +} + +auto ChaoticGoodServerTransport::TransportReadLoop() { + return Loop([this] { + return TrySeq( + transport_.ReadFrameBytes(), + [this](std::tuple frame_bytes) { + const auto& frame_header = std::get<0>(frame_bytes); + auto& buffers = std::get<1>(frame_bytes); + return Switch( + frame_header.type, + Case(FrameType::kSettings, + []() -> absl::Status { + return absl::InternalError("Unexpected settings frame"); + }), + Case(FrameType::kFragment, + [this, &frame_header, &buffers]() { + return If( + frame_header.flags.is_set(0), + [this, &frame_header, &buffers]() { + return DeserializeAndPushFragmentToNewCall( + frame_header, std::move(buffers)); + }, + [this, &frame_header, &buffers]() { + return DeserializeAndPushFragmentToExistingCall( + frame_header, std::move(buffers)); + }); + }), + Case(FrameType::kCancel, + [this, &frame_header]() { + absl::optional call_initiator = + ExtractStream(frame_header.stream_id); + return If( + call_initiator.has_value(), + [&call_initiator]() { + auto c = std::move(*call_initiator); + return c.SpawnWaitable("cancel", [c]() mutable { + c.Cancel(); + return absl::OkStatus(); + }); + }, + []() -> absl::Status { + return absl::InternalError( + "Unexpected cancel frame"); + }); + }), + Default([frame_header]() { + return absl::InternalError( + absl::StrCat("Unexpected frame type: ", + static_cast(frame_header.type))); + })); + }, + []() -> LoopCtl { return Continue{}; }); + }); +} + +auto ChaoticGoodServerTransport::OnTransportActivityDone() { + return [this](absl::Status status) { + if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) { + this->AbortWithError(); + } + }; +} + +ChaoticGoodServerTransport::ChaoticGoodServerTransport( + const ChannelArgs& args, std::unique_ptr control_endpoint, + std::unique_ptr data_endpoint, + std::shared_ptr event_engine) + : outgoing_frames_(4), + transport_(std::move(control_endpoint), std::move(data_endpoint)), + allocator_(args.GetObject() + ->memory_quota() + ->CreateMemoryAllocator("chaotic-good")), + event_engine_(event_engine), + writer_{MakeActivity(TransportWriteLoop(), + EventEngineWakeupScheduler(event_engine), + OnTransportActivityDone())}, + reader_{nullptr} {} + +void ChaoticGoodServerTransport::SetAcceptor(Acceptor* acceptor) { + GPR_ASSERT(acceptor_ == nullptr); + GPR_ASSERT(acceptor != nullptr); + acceptor_ = acceptor; + reader_ = MakeActivity(TransportReadLoop(), + EventEngineWakeupScheduler(event_engine_), + OnTransportActivityDone()); +} + +ChaoticGoodServerTransport::~ChaoticGoodServerTransport() { + if (writer_ != nullptr) { + writer_.reset(); + } + if (reader_ != nullptr) { + reader_.reset(); + } +} + +void ChaoticGoodServerTransport::AbortWithError() { + // Mark transport as unavailable when the endpoint write/read failed. + // Close all the available pipes. + outgoing_frames_.MarkClosed(); + ReleasableMutexLock lock(&mu_); + StreamMap stream_map = std::move(stream_map_); + stream_map_.clear(); + lock.Release(); + for (const auto& pair : stream_map) { + auto call_initiator = pair.second; + call_initiator.SpawnInfallible("cancel", [call_initiator]() mutable { + call_initiator.Cancel(); + return Empty{}; + }); + } +} + +absl::optional ChaoticGoodServerTransport::LookupStream( + uint32_t stream_id) { + MutexLock lock(&mu_); + auto it = stream_map_.find(stream_id); + if (it == stream_map_.end()) return absl::nullopt; + return it->second; +} + +absl::optional ChaoticGoodServerTransport::ExtractStream( + uint32_t stream_id) { + MutexLock lock(&mu_); + auto it = stream_map_.find(stream_id); + if (it == stream_map_.end()) return absl::nullopt; + auto r = std::move(it->second); + stream_map_.erase(it); + return std::move(r); +} + +} // namespace chaotic_good +} // namespace grpc_core diff --git a/src/core/ext/transport/chaotic_good/server_transport.h b/src/core/ext/transport/chaotic_good/server_transport.h new file mode 100644 index 00000000000..9ce92928385 --- /dev/null +++ b/src/core/ext/transport/chaotic_good/server_transport.h @@ -0,0 +1,145 @@ +// Copyright 2022 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_EXT_TRANSPORT_CHAOTIC_GOOD_SERVER_TRANSPORT_H +#define GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SERVER_TRANSPORT_H + +#include + +#include +#include + +#include +#include // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" +#include "absl/random/random.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/types/optional.h" +#include "absl/types/variant.h" + +#include +#include +#include +#include + +#include "src/core/ext/transport/chaotic_good/chaotic_good_transport.h" +#include "src/core/ext/transport/chaotic_good/frame.h" +#include "src/core/ext/transport/chaotic_good/frame_header.h" +#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" +#include "src/core/ext/transport/chttp2/transport/hpack_parser.h" +#include "src/core/lib/event_engine/default_event_engine.h" // IWYU pragma: keep +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/promise/activity.h" +#include "src/core/lib/promise/context.h" +#include "src/core/lib/promise/if.h" +#include "src/core/lib/promise/inter_activity_pipe.h" +#include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/mpsc.h" +#include "src/core/lib/promise/party.h" +#include "src/core/lib/promise/pipe.h" +#include "src/core/lib/promise/poll.h" +#include "src/core/lib/promise/seq.h" +#include "src/core/lib/promise/try_join.h" +#include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/resource_quota/arena.h" +#include "src/core/lib/resource_quota/memory_quota.h" +#include "src/core/lib/slice/slice.h" +#include "src/core/lib/slice/slice_buffer.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/promise_endpoint.h" +#include "src/core/lib/transport/transport.h" + +namespace grpc_core { +namespace chaotic_good { + +class ChaoticGoodServerTransport final : public Transport, + public ServerTransport { + public: + ChaoticGoodServerTransport( + const ChannelArgs& args, + std::unique_ptr control_endpoint, + std::unique_ptr data_endpoint, + std::shared_ptr + event_engine); + ~ChaoticGoodServerTransport() override; + + FilterStackTransport* filter_stack_transport() override { return nullptr; } + ClientTransport* client_transport() override { return nullptr; } + ServerTransport* server_transport() override { return this; } + absl::string_view GetTransportName() const override { return "chaotic_good"; } + void SetPollset(grpc_stream*, grpc_pollset*) override {} + void SetPollsetSet(grpc_stream*, grpc_pollset_set*) override {} + void PerformOp(grpc_transport_op*) override { Crash("unimplemented"); } + grpc_endpoint* GetEndpoint() override { return nullptr; } + void Orphan() override { delete this; } + + void SetAcceptor(Acceptor* acceptor) override; + void AbortWithError(); + + private: + using StreamMap = absl::flat_hash_map; + + absl::Status NewStream(uint32_t stream_id, CallInitiator call_initiator); + absl::optional LookupStream(uint32_t stream_id); + absl::optional ExtractStream(uint32_t stream_id); + auto CallOutboundLoop(uint32_t stream_id, CallInitiator call_initiator); + auto OnTransportActivityDone(); + auto TransportReadLoop(); + auto TransportWriteLoop(); + // Read different parts of the server frame from control/data endpoints + // based on frame header. + // Resolves to a StatusOr> + auto ReadFrameBody(Slice read_buffer); + void SendCancel(uint32_t stream_id, absl::Status why); + auto DeserializeAndPushFragmentToNewCall(FrameHeader frame_header, + BufferPair buffers); + auto DeserializeAndPushFragmentToExistingCall(FrameHeader frame_header, + BufferPair buffers); + auto MaybePushFragmentIntoCall(absl::optional call_initiator, + absl::Status error, ClientFragmentFrame frame); + auto PushFragmentIntoCall(CallInitiator call_initiator, + ClientFragmentFrame frame); + + Acceptor* acceptor_ = nullptr; + MpscReceiver outgoing_frames_; + ChaoticGoodTransport transport_; + // Assigned aligned bytes from setting frame. + size_t aligned_bytes_ = 64; + Mutex mu_; + // Map of stream incoming server frames, key is stream_id. + StreamMap stream_map_ ABSL_GUARDED_BY(mu_); + grpc_event_engine::experimental::MemoryAllocator allocator_; + std::shared_ptr event_engine_; + ActivityPtr writer_; + ActivityPtr reader_; +}; + +} // namespace chaotic_good +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SERVER_TRANSPORT_H \ No newline at end of file diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index cc932d0f216..24fdd41d387 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -36,8 +36,8 @@ class InprocServerTransport final : public RefCounted, public Transport, public ServerTransport { public: - void SetAcceptFunction(AcceptFunction accept_function) override { - accept_ = std::move(accept_function); + void SetAcceptor(Acceptor* acceptor) override { + acceptor_ = acceptor; ConnectionState expect = ConnectionState::kInitial; state_.compare_exchange_strong(expect, ConnectionState::kReady, std::memory_order_acq_rel, @@ -92,7 +92,7 @@ class InprocServerTransport final : public RefCounted, case ConnectionState::kReady: break; } - return accept_(md); + return acceptor_->CreateCall(md, acceptor_->CreateArena()); } private: @@ -100,7 +100,7 @@ class InprocServerTransport final : public RefCounted, std::atomic state_{ConnectionState::kInitial}; std::atomic disconnecting_{false}; - AcceptFunction accept_; + Acceptor* acceptor_; absl::Status disconnect_error_; Mutex state_tracker_mu_; ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(state_tracker_mu_){ diff --git a/src/core/lib/gprpp/debug_location.h b/src/core/lib/gprpp/debug_location.h index 7e021fd9f78..c6c9b682869 100644 --- a/src/core/lib/gprpp/debug_location.h +++ b/src/core/lib/gprpp/debug_location.h @@ -81,6 +81,15 @@ class DebugLocation { }; #endif +template +struct ValueWithDebugLocation { + // NOLINTNEXTLINE + ValueWithDebugLocation(T&& value, DebugLocation debug_location = {}) + : value(std::forward(value)), debug_location(debug_location) {} + T value; + GPR_NO_UNIQUE_ADDRESS DebugLocation debug_location; +}; + #define DEBUG_LOCATION ::grpc_core::DebugLocation(__FILE__, __LINE__) } // namespace grpc_core diff --git a/src/core/lib/promise/detail/status.h b/src/core/lib/promise/detail/status.h index 1063f329193..bfc649e6c48 100644 --- a/src/core/lib/promise/detail/status.h +++ b/src/core/lib/promise/detail/status.h @@ -45,6 +45,11 @@ inline absl::Status IntoStatus(absl::Status* status) { // can participate in TrySeq as result types that affect control flow. inline bool IsStatusOk(const absl::Status& status) { return status.ok(); } +template +inline bool IsStatusOk(const absl::StatusOr& status) { + return status.ok(); +} + template struct StatusCastImpl; @@ -59,20 +64,52 @@ struct StatusCastImpl { }; template -struct StatusCastImpl, absl::Status> { - static absl::StatusOr Cast(absl::Status&& t) { return std::move(t); } +struct StatusCastImpl> { + static absl::Status Cast(absl::StatusOr&& t) { + return std::move(t.status()); + } }; template -struct StatusCastImpl, const absl::Status&> { - static absl::StatusOr Cast(const absl::Status& t) { return t; } +struct StatusCastImpl&> { + static absl::Status Cast(const absl::StatusOr& t) { return t.status(); } }; +template +struct StatusCastImpl&> { + static absl::Status Cast(const absl::StatusOr& t) { return t.status(); } +}; + +// StatusCast<> allows casting from one status-bearing type to another, +// regardless of whether the status indicates success or failure. +// This means that we can go from StatusOr to Status safely, but not in the +// opposite direction. +// For cases where the status is guaranteed to be a failure (and hence not +// needing to preserve values) see FailureStatusCast<> below. template To StatusCast(From&& from) { return StatusCastImpl::Cast(std::forward(from)); } +template +struct FailureStatusCastImpl : public StatusCastImpl {}; + +template +struct FailureStatusCastImpl, absl::Status> { + static absl::StatusOr Cast(absl::Status&& t) { return std::move(t); } +}; + +template +struct FailureStatusCastImpl, const absl::Status&> { + static absl::StatusOr Cast(const absl::Status& t) { return t; } +}; + +template +To FailureStatusCast(From&& from) { + GPR_DEBUG_ASSERT(!IsStatusOk(from)); + return FailureStatusCastImpl::Cast(std::forward(from)); +} + } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_PROMISE_DETAIL_STATUS_H diff --git a/src/core/lib/promise/event_engine_wakeup_scheduler.h b/src/core/lib/promise/event_engine_wakeup_scheduler.h index 792ee9d4439..3e489c87fc6 100644 --- a/src/core/lib/promise/event_engine_wakeup_scheduler.h +++ b/src/core/lib/promise/event_engine_wakeup_scheduler.h @@ -33,7 +33,9 @@ class EventEngineWakeupScheduler { explicit EventEngineWakeupScheduler( std::shared_ptr event_engine) - : event_engine_(std::move(event_engine)) {} + : event_engine_(std::move(event_engine)) { + GPR_ASSERT(event_engine_ != nullptr); + } template class BoundScheduler diff --git a/src/core/lib/promise/if.h b/src/core/lib/promise/if.h index e659ad30ed8..2c81fd7e38a 100644 --- a/src/core/lib/promise/if.h +++ b/src/core/lib/promise/if.h @@ -192,6 +192,10 @@ class If { // If it returns failure, returns failure for the entire combinator. // If it returns true, evaluates the second promise. // If it returns false, evaluates the third promise. +// If C is a constant, it's guaranteed that one of the promise factories +// if_true or if_false will be evaluated before returning from this function. +// This makes it safe to capture lambda arguments in the promise factory by +// reference. template promise_detail::If If(C condition, T if_true, F if_false) { return promise_detail::If(std::move(condition), std::move(if_true), diff --git a/src/core/lib/promise/inter_activity_pipe.h b/src/core/lib/promise/inter_activity_pipe.h index a7594fb26a2..4578cbb3c62 100644 --- a/src/core/lib/promise/inter_activity_pipe.h +++ b/src/core/lib/promise/inter_activity_pipe.h @@ -113,9 +113,9 @@ class InterActivityPipe { if (center_ != nullptr) center_->MarkClosed(); } - bool IsClose() { return center_->IsClosed(); } + bool IsClosed() { return center_->IsClosed(); } - void MarkClose() { + void MarkClosed() { if (center_ != nullptr) center_->MarkClosed(); } @@ -146,6 +146,12 @@ class InterActivityPipe { return [center = center_]() { return center->Next(); }; } + bool IsClose() { return center_->IsClosed(); } + + void MarkClose() { + if (center_ != nullptr) center_->MarkClosed(); + } + private: RefCountedPtr
center_; }; diff --git a/src/core/lib/promise/mpsc.h b/src/core/lib/promise/mpsc.h index c12544282f6..8bbbfc4c8ec 100644 --- a/src/core/lib/promise/mpsc.h +++ b/src/core/lib/promise/mpsc.h @@ -103,14 +103,12 @@ class Center : public RefCounted> { // Mark that the receiver is closed. void ReceiverClosed() { - MutexLock lock(&mu_); + ReleasableMutexLock lock(&mu_); + if (receiver_closed_) return; receiver_closed_ = true; - } - - // Return whether the receiver is closed. - bool IsClosed() { - MutexLock lock(&mu_); - return receiver_closed_; + auto wakeups = send_wakers_.TakeWakeupSet(); + lock.Release(); + wakeups.Wakeup(); } private: @@ -131,8 +129,8 @@ class MpscReceiver; template class MpscSender { public: - MpscSender(const MpscSender&) = delete; - MpscSender& operator=(const MpscSender&) = delete; + MpscSender(const MpscSender&) = default; + MpscSender& operator=(const MpscSender&) = default; MpscSender(MpscSender&&) noexcept = default; MpscSender& operator=(MpscSender&&) noexcept = default; @@ -140,7 +138,10 @@ class MpscSender { // Resolves to true if sent, false if the receiver was closed (and the value // will never be successfully sent). auto Send(T t) { - return [this, t = std::move(t)]() mutable { return center_->PollSend(t); }; + return [center = center_, t = std::move(t)]() mutable -> Poll { + if (center == nullptr) return false; + return center->PollSend(t); + }; } bool UnbufferedImmediateSend(T t) { @@ -170,7 +171,6 @@ class MpscReceiver { ~MpscReceiver() { if (center_ != nullptr) center_->ReceiverClosed(); } - bool IsClosed() { return center_->IsClosed(); } void MarkClosed() { if (center_ != nullptr) center_->ReceiverClosed(); } diff --git a/src/core/lib/promise/status_flag.h b/src/core/lib/promise/status_flag.h index d9067509c32..c8c9c0ba41e 100644 --- a/src/core/lib/promise/status_flag.h +++ b/src/core/lib/promise/status_flag.h @@ -95,6 +95,30 @@ struct StatusCastImpl { } }; +template +struct FailureStatusCastImpl, StatusFlag> { + static absl::StatusOr Cast(StatusFlag flag) { + GPR_DEBUG_ASSERT(!flag.ok()); + return absl::CancelledError(); + } +}; + +template +struct FailureStatusCastImpl, StatusFlag&> { + static absl::StatusOr Cast(StatusFlag flag) { + GPR_DEBUG_ASSERT(!flag.ok()); + return absl::CancelledError(); + } +}; + +template +struct FailureStatusCastImpl, const StatusFlag&> { + static absl::StatusOr Cast(StatusFlag flag) { + GPR_DEBUG_ASSERT(!flag.ok()); + return absl::CancelledError(); + } +}; + // A value if an operation was successful, or a failure flag if not. template class ValueOrFailure { diff --git a/src/core/lib/promise/try_join.h b/src/core/lib/promise/try_join.h index be3354dc9b7..29cd06d5be4 100644 --- a/src/core/lib/promise/try_join.h +++ b/src/core/lib/promise/try_join.h @@ -75,16 +75,16 @@ struct TryJoinTraits { } template static R EarlyReturn(absl::Status x) { - return StatusCast(std::move(x)); + return FailureStatusCast(std::move(x)); } template static R EarlyReturn(StatusFlag x) { - return StatusCast(x); + return FailureStatusCast(x); } template static R EarlyReturn(const ValueOrFailure& x) { GPR_ASSERT(!x.ok()); - return StatusCast(Failure{}); + return FailureStatusCast(Failure{}); } template static auto FinalReturn(A&&... a) { diff --git a/src/core/lib/promise/try_seq.h b/src/core/lib/promise/try_seq.h index ca04904ab1d..ab9777d1afb 100644 --- a/src/core/lib/promise/try_seq.h +++ b/src/core/lib/promise/try_seq.h @@ -76,7 +76,7 @@ struct TrySeqTraitsWithSfinae> { } template static R ReturnValue(absl::StatusOr&& status) { - return StatusCast(status.status()); + return FailureStatusCast(status.status()); } template static auto CallSeqFactory(F& f, Elem&& elem, absl::StatusOr value) @@ -86,11 +86,26 @@ struct TrySeqTraitsWithSfinae> { template static Poll CheckResultAndRunNext(absl::StatusOr prior, RunNext run_next) { - if (!prior.ok()) return StatusCast(prior.status()); + if (!prior.ok()) return FailureStatusCast(prior.status()); return run_next(std::move(prior)); } }; +template +struct AllowGenericTrySeqTraits { + static constexpr bool value = true; +}; + +template <> +struct AllowGenericTrySeqTraits { + static constexpr bool value = false; +}; + +template +struct AllowGenericTrySeqTraits> { + static constexpr bool value = false; +}; + template struct TakeValueExists { static constexpr bool value = false; @@ -107,7 +122,7 @@ template struct TrySeqTraitsWithSfinae< T, absl::enable_if_t< std::is_same())), bool>::value && - !TakeValueExists::value, + !TakeValueExists::value && AllowGenericTrySeqTraits::value, void>> { using UnwrappedType = void; using WrappedType = T; @@ -121,7 +136,7 @@ struct TrySeqTraitsWithSfinae< } template static R ReturnValue(T&& status) { - return StatusCast(std::move(status)); + return FailureStatusCast(std::move(status)); } template static Poll CheckResultAndRunNext(T prior, RunNext run_next) { @@ -133,7 +148,7 @@ template struct TrySeqTraitsWithSfinae< T, absl::enable_if_t< std::is_same())), bool>::value && - TakeValueExists::value, + TakeValueExists::value && AllowGenericTrySeqTraits::value, void>> { using UnwrappedType = decltype(TakeValue(std::declval())); using WrappedType = T; @@ -148,7 +163,7 @@ struct TrySeqTraitsWithSfinae< template static R ReturnValue(T&& status) { GPR_DEBUG_ASSERT(!IsStatusOk(status)); - return StatusCast(status.status()); + return FailureStatusCast(status.status()); } template static Poll CheckResultAndRunNext(T prior, RunNext run_next) { @@ -170,7 +185,7 @@ struct TrySeqTraitsWithSfinae { } template static R ReturnValue(absl::Status&& status) { - return StatusCast(std::move(status)); + return FailureStatusCast(std::move(status)); } template static Poll CheckResultAndRunNext(absl::Status prior, diff --git a/src/core/lib/resource_quota/arena.h b/src/core/lib/resource_quota/arena.h index 9c0c812d4c3..edcab2caf87 100644 --- a/src/core/lib/resource_quota/arena.h +++ b/src/core/lib/resource_quota/arena.h @@ -180,7 +180,7 @@ class Arena { template T* New(Args&&... args) { T* t = static_cast(Alloc(sizeof(T))); - Construct(t, std::forward(args)...); + new (t) T(std::forward(args)...); return t; } @@ -333,7 +333,7 @@ class Arena { // value in Arena::PoolSizes, and so this may pessimize total // arena size. template - PoolPtr MakePooled(Args&&... args) { + static PoolPtr MakePooled(Args&&... args) { return PoolPtr(new T(std::forward(args)...), PooledDeleter()); } diff --git a/src/core/lib/slice/slice_buffer.h b/src/core/lib/slice/slice_buffer.h index 2626bd4a0e9..0c1bfe9d901 100644 --- a/src/core/lib/slice/slice_buffer.h +++ b/src/core/lib/slice/slice_buffer.h @@ -50,6 +50,9 @@ namespace grpc_core { class SliceBuffer { public: explicit SliceBuffer() { grpc_slice_buffer_init(&slice_buffer_); } + explicit SliceBuffer(Slice slice) : SliceBuffer() { + Append(std::move(slice)); + } SliceBuffer(const SliceBuffer& other) = delete; SliceBuffer(SliceBuffer&& other) noexcept { grpc_slice_buffer_init(&slice_buffer_); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d5dbc54be39..2702bedc0e7 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -4063,16 +4063,13 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, } RefCountedPtr MakeServerCall(Server* server, - Channel* channel) { - const auto initial_size = channel->CallSizeEstimate(); - global_stats().IncrementCallInitialSize(initial_size); - auto alloc = Arena::CreateWithAlloc(initial_size, sizeof(ServerCallSpine), - channel->allocator()); - auto* call = new (alloc.second) ServerCallSpine(server, channel, alloc.first); - return RefCountedPtr(call); + Channel* channel, + Arena* arena) { + return RefCountedPtr( + arena->New(server, channel, arena)); } #else -RefCountedPtr MakeServerCall(Server*, Channel*) { +RefCountedPtr MakeServerCall(Server*, Channel*, Arena*) { Crash("not implemented"); } #endif diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 6653bb6a0dd..520cf13505c 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -160,7 +160,8 @@ template <> struct ContextType {}; RefCountedPtr MakeServerCall(Server* server, - Channel* channel); + Channel* channel, + Arena* arena); } // namespace grpc_core diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 44b541a8593..e53a609cfb1 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -51,6 +51,7 @@ #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/config/core_configuration.h" +#include "src/core/lib/debug/stats.h" #include "src/core/lib/experiments/experiments.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/crash.h" @@ -1297,6 +1298,20 @@ Server::ChannelData::~ChannelData() { } } +Arena* Server::ChannelData::CreateArena() { + const auto initial_size = channel_->CallSizeEstimate(); + global_stats().IncrementCallInitialSize(initial_size); + return Arena::Create(initial_size, channel_->allocator()); +} + +absl::StatusOr Server::ChannelData::CreateCall( + ClientMetadata& client_initial_metadata, Arena* arena) { + SetRegisteredMethodOnMetadata(client_initial_metadata); + auto call = MakeServerCall(server_.get(), channel_.get(), arena); + InitCall(call); + return CallInitiator(std::move(call)); +} + void Server::ChannelData::InitTransport(RefCountedPtr server, RefCountedPtr channel, size_t cq_idx, Transport* transport, @@ -1329,13 +1344,7 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, } if (transport->server_transport() != nullptr) { ++accept_stream_types; - transport->server_transport()->SetAcceptFunction( - [this](ClientMetadata& metadata) { - SetRegisteredMethodOnMetadata(metadata); - auto call = MakeServerCall(server_.get(), channel_.get()); - InitCall(call); - return CallInitiator(std::move(call)); - }); + transport->server_transport()->SetAcceptor(this); } GPR_ASSERT(accept_stream_types == 1); op->start_connectivity_watch = MakeOrphanable(this); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 11ec7c68a45..4bb6fce3fae 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -218,7 +218,7 @@ class Server : public InternallyRefCounted, class AllocatingRequestMatcherBatch; class AllocatingRequestMatcherRegistered; - class ChannelData { + class ChannelData final : public ServerTransport::Acceptor { public: ChannelData() = default; ~ChannelData(); @@ -241,6 +241,10 @@ class Server : public InternallyRefCounted, grpc_channel_element* elem, CallArgs call_args, NextPromiseFactory); void InitCall(RefCountedPtr call); + Arena* CreateArena() override; + absl::StatusOr CreateCall( + ClientMetadata& client_initial_metadata, Arena* arena) override; + private: class ConnectivityWatcher; diff --git a/src/core/lib/transport/promise_endpoint.h b/src/core/lib/transport/promise_endpoint.h index 2c2b3a2d37c..fbdc467cbb8 100644 --- a/src/core/lib/transport/promise_endpoint.h +++ b/src/core/lib/transport/promise_endpoint.h @@ -69,24 +69,26 @@ class PromiseEndpoint { auto Write(SliceBuffer data) { // Assert previous write finishes. GPR_ASSERT(!write_state_->complete.load(std::memory_order_relaxed)); - // TODO(ladynana): Replace this with `SliceBufferCast<>` when it is - // available. - grpc_slice_buffer_swap(write_state_->buffer.c_slice_buffer(), - data.c_slice_buffer()); - // If `Write()` returns true immediately, the callback will not be called. - // We still need to call our callback to pick up the result. - write_state_->waker = Activity::current()->MakeNonOwningWaker(); - const bool completed = endpoint_->Write( - [write_state = write_state_](absl::Status status) { - write_state->Complete(std::move(status)); - }, - &write_state_->buffer, nullptr /* uses default arguments */); + bool completed; + if (data.Length() == 0) { + completed = true; + } else { + // TODO(ladynana): Replace this with `SliceBufferCast<>` when it is + // available. + grpc_slice_buffer_swap(write_state_->buffer.c_slice_buffer(), + data.c_slice_buffer()); + // If `Write()` returns true immediately, the callback will not be called. + // We still need to call our callback to pick up the result. + write_state_->waker = Activity::current()->MakeNonOwningWaker(); + completed = endpoint_->Write( + [write_state = write_state_](absl::Status status) { + write_state->Complete(std::move(status)); + }, + &write_state_->buffer, nullptr /* uses default arguments */); + if (completed) write_state_->waker = Waker(); + } return If( - completed, - [this]() { - write_state_->waker = Waker(); - return []() { return absl::OkStatus(); }; - }, + completed, []() { return []() { return absl::OkStatus(); }; }, [this]() { return [write_state = write_state_]() -> Poll { // If current write isn't finished return `Pending()`, else return diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index ab405804065..bad5c4b8590 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -291,9 +291,8 @@ void ForwardCall(CallHandler call_handler, CallInitiator call_initiator, return call_initiator.SpawnWaitable( "send_message", [msg = std::move(msg), call_initiator]() mutable { - return call_initiator.CancelIfFails(Map( - call_initiator.PushMessage(std::move(msg)), - [](bool r) { return StatusFlag(r); })); + return call_initiator.CancelIfFails( + call_initiator.PushMessage(std::move(msg))); }); }); }); @@ -317,8 +316,7 @@ void ForwardCall(CallHandler call_handler, CallInitiator call_initiator, "recv_message", [msg = std::move(msg), call_handler]() mutable { return call_handler.CancelIfFails( - Map(call_handler.PushMessage(std::move(msg)), - [](bool r) { return StatusFlag(r); })); + call_handler.PushMessage(std::move(msg))); }); }), ImmediateOkStatus())), @@ -334,4 +332,10 @@ void ForwardCall(CallHandler call_handler, CallInitiator call_initiator, }); } +CallInitiatorAndHandler MakeCall( + grpc_event_engine::experimental::EventEngine* event_engine, Arena* arena) { + auto spine = CallSpine::Create(event_engine, arena); + return {CallInitiator(spine), CallHandler(spine)}; +} + } // namespace grpc_core diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index c9f138c8f09..5a7e09bdb43 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -258,6 +258,20 @@ class CallSpineInterface { virtual Pipe& server_to_client_messages() = 0; virtual Pipe& server_trailing_metadata() = 0; virtual Latch& cancel_latch() = 0; + // Add a callback to be called when server trailing metadata is received. + void OnDone(absl::AnyInvocable fn) { + if (on_done_ == nullptr) { + on_done_ = std::move(fn); + return; + } + on_done_ = [first = std::move(fn), next = std::move(on_done_)]() mutable { + first(); + next(); + }; + } + void CallOnDone() { + if (on_done_ != nullptr) std::exchange(on_done_, nullptr)(); + } virtual Party& party() = 0; virtual void IncrementRefCount() = 0; virtual void Unref() = 0; @@ -276,6 +290,11 @@ class CallSpineInterface { auto& c = cancel_latch(); if (c.is_set()) return absl::nullopt; c.Set(std::move(metadata)); + CallOnDone(); + client_initial_metadata().sender.CloseWithError(); + server_initial_metadata().sender.CloseWithError(); + client_to_server_messages().sender.CloseWithError(); + server_to_client_messages().sender.CloseWithError(); return absl::nullopt; } @@ -325,11 +344,18 @@ class CallSpineInterface { } }); } + + private: + absl::AnyInvocable on_done_{nullptr}; }; -class CallSpine final : public CallSpineInterface { +class CallSpine final : public CallSpineInterface, public Party { public: - CallSpine() { Crash("unimplemented"); } + static RefCountedPtr Create( + grpc_event_engine::experimental::EventEngine* event_engine, + Arena* arena) { + return RefCountedPtr(arena->New(event_engine, arena)); + } Pipe& client_initial_metadata() override { return client_initial_metadata_; @@ -347,23 +373,57 @@ class CallSpine final : public CallSpineInterface { return server_trailing_metadata_; } Latch& cancel_latch() override { return cancel_latch_; } - Party& party() override { Crash("unimplemented"); } - void IncrementRefCount() override { Crash("unimplemented"); } - void Unref() override { Crash("unimplemented"); } + Party& party() override { return *this; } + void IncrementRefCount() override { Party::IncrementRefCount(); } + void Unref() override { Party::Unref(); } private: + friend class Arena; + CallSpine(grpc_event_engine::experimental::EventEngine* event_engine, + Arena* arena) + : Party(arena, 1), event_engine_(event_engine) {} + + class ScopedContext : public ScopedActivity, + public promise_detail::Context { + public: + explicit ScopedContext(CallSpine* spine) + : ScopedActivity(&spine->party()), Context(spine->arena()) {} + }; + + bool RunParty() override { + ScopedContext context(this); + return Party::RunParty(); + } + + void PartyOver() override { + Arena* a = arena(); + { + ScopedContext context(this); + CancelRemainingParticipants(); + a->DestroyManagedNewObjects(); + } + this->~CallSpine(); + a->Destroy(); + } + + grpc_event_engine::experimental::EventEngine* event_engine() const override { + return event_engine_; + } + // Initial metadata from client to server - Pipe client_initial_metadata_; + Pipe client_initial_metadata_{arena()}; // Initial metadata from server to client - Pipe server_initial_metadata_; + Pipe server_initial_metadata_{arena()}; // Messages travelling from the application to the transport. - Pipe client_to_server_messages_; + Pipe client_to_server_messages_{arena()}; // Messages travelling from the transport to the application. - Pipe server_to_client_messages_; + Pipe server_to_client_messages_{arena()}; // Trailing metadata from server to client - Pipe server_trailing_metadata_; + Pipe server_trailing_metadata_{arena()}; // Latch that can be set to terminate the call Latch cancel_latch_; + // Event engine associated with this call + grpc_event_engine::experimental::EventEngine* const event_engine_; }; class CallInitiator { @@ -405,7 +465,14 @@ class CallInitiator { auto PushMessage(MessageHandle message) { GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); - return spine_->client_to_server_messages().sender.Push(std::move(message)); + return Map( + spine_->client_to_server_messages().sender.Push(std::move(message)), + [](bool r) { return StatusFlag(r); }); + } + + void FinishSends() { + GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); + spine_->client_to_server_messages().sender.Close(); } template @@ -413,6 +480,12 @@ class CallInitiator { return spine_->CancelIfFails(std::move(promise)); } + void Cancel() { + GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); + std::ignore = + spine_->Cancel(ServerMetadataFromStatus(absl::CancelledError())); + } + template void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) { spine_->SpawnGuarded(name, std::move(promise_factory)); @@ -428,8 +501,10 @@ class CallInitiator { return spine_->party().SpawnWaitable(name, std::move(promise_factory)); } + Arena* arena() { return spine_->party().arena(); } + private: - const RefCountedPtr spine_; + RefCountedPtr spine_; }; class CallHandler { @@ -447,14 +522,16 @@ class CallHandler { }); } - auto PushServerInitialMetadata(ClientMetadataHandle md) { + auto PushServerInitialMetadata(ServerMetadataHandle md) { GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); return Map(spine_->server_initial_metadata().sender.Push(std::move(md)), [](bool ok) { return StatusFlag(ok); }); } - auto PushServerTrailingMetadata(ClientMetadataHandle md) { + auto PushServerTrailingMetadata(ServerMetadataHandle md) { GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); + spine_->server_to_client_messages().sender.Close(); + spine_->CallOnDone(); return Map(spine_->server_trailing_metadata().sender.Push(std::move(md)), [](bool ok) { return StatusFlag(ok); }); } @@ -466,9 +543,18 @@ class CallHandler { auto PushMessage(MessageHandle message) { GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); - return spine_->server_to_client_messages().sender.Push(std::move(message)); + return Map( + spine_->server_to_client_messages().sender.Push(std::move(message)), + [](bool ok) { return StatusFlag(ok); }); } + void Cancel(ServerMetadataHandle status) { + GPR_DEBUG_ASSERT(Activity::current() == &spine_->party()); + std::ignore = spine_->Cancel(std::move(status)); + } + + void OnDone(absl::AnyInvocable fn) { spine_->OnDone(std::move(fn)); } + template auto CancelIfFails(Promise promise) { return spine_->CancelIfFails(std::move(promise)); @@ -489,8 +575,10 @@ class CallHandler { return spine_->party().SpawnWaitable(name, std::move(promise_factory)); } + Arena* arena() { return spine_->party().arena(); } + private: - const RefCountedPtr spine_; + RefCountedPtr spine_; }; struct CallInitiatorAndHandler { @@ -498,13 +586,16 @@ struct CallInitiatorAndHandler { CallHandler handler; }; +CallInitiatorAndHandler MakeCall( + grpc_event_engine::experimental::EventEngine* event_engine, Arena* arena); + template -auto OutgoingMessages(CallHalf& h) { +auto OutgoingMessages(CallHalf h) { struct Wrapper { - CallHalf& h; + CallHalf h; auto Next() { return h.PullMessage(); } }; - return Wrapper{h}; + return Wrapper{std::move(h)}; } // Forward a call from `call_handler` to `call_initiator` (with initial metadata @@ -925,14 +1016,24 @@ class ClientTransport { class ServerTransport { public: - // AcceptFunction takes initial metadata for a new call and returns a - // CallInitiator object for it, for the transport to use to communicate with - // the CallHandler object passed to the application. - using AcceptFunction = - absl::AnyInvocable(ClientMetadata&) const>; + // 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( + ClientMetadata& client_initial_metadata, Arena* arena) = 0; + + protected: + ~Acceptor() = default; + }; // Called once slightly after transport setup to register the accept function. - virtual void SetAcceptFunction(AcceptFunction accept_function) = 0; + virtual void SetAcceptor(Acceptor* acceptor) = 0; protected: ~ServerTransport() = default; diff --git a/test/core/promise/mpsc_test.cc b/test/core/promise/mpsc_test.cc index 38baa68cb60..3d6e669a173 100644 --- a/test/core/promise/mpsc_test.cc +++ b/test/core/promise/mpsc_test.cc @@ -95,6 +95,8 @@ TEST(MpscTest, SendingLotsOfThingsGivesPushback) { EXPECT_EQ(NowOrNever(sender.Send(MakePayload(1))), true); EXPECT_EQ(NowOrNever(sender.Send(MakePayload(2))), absl::nullopt); activity1.Deactivate(); + + EXPECT_CALL(activity1, WakeupRequested()); } TEST(MpscTest, ReceivingAfterBlockageWakesUp) { diff --git a/test/core/transport/chaotic_good/BUILD b/test/core/transport/chaotic_good/BUILD index fc698aeec44..11daa792100 100644 --- a/test/core/transport/chaotic_good/BUILD +++ b/test/core/transport/chaotic_good/BUILD @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package") -load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") +load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer", "grpc_proto_fuzzer") licenses(["notice"]) @@ -22,6 +22,34 @@ grpc_package( visibility = "tests", ) +grpc_cc_library( + name = "mock_promise_endpoint", + testonly = 1, + srcs = ["mock_promise_endpoint.cc"], + hdrs = ["mock_promise_endpoint.h"], + external_deps = ["gtest"], + deps = [ + "//:grpc", + "//src/core:grpc_promise_endpoint", + ], +) + +grpc_cc_library( + name = "transport_test", + testonly = 1, + srcs = ["transport_test.cc"], + hdrs = ["transport_test.h"], + external_deps = ["gtest"], + deps = [ + "//:iomgr_timer", + "//src/core:chaotic_good_frame", + "//src/core:memory_quota", + "//src/core:resource_quota", + "//test/core/event_engine/fuzzing_event_engine", + "//test/core/event_engine/fuzzing_event_engine:fuzzing_event_engine_proto", + ], +) + grpc_cc_test( name = "frame_header_test", srcs = ["frame_header_test.cc"], @@ -54,7 +82,7 @@ grpc_cc_test( deps = ["//src/core:chaotic_good_frame"], ) -grpc_fuzzer( +grpc_proto_fuzzer( name = "frame_fuzzer", srcs = ["frame_fuzzer.cc"], corpus = "frame_fuzzer_corpus", @@ -63,7 +91,10 @@ grpc_fuzzer( "absl/status:statusor", ], language = "C++", + proto = "frame_fuzzer.proto", tags = ["no_windows"], + uses_event_engine = False, + uses_polling = False, deps = [ "//:exec_ctx", "//:gpr", @@ -96,26 +127,16 @@ grpc_cc_test( uses_event_engine = False, uses_polling = False, deps = [ + "mock_promise_endpoint", + "transport_test", "//:grpc", "//:grpc_public_hdrs", - "//:iomgr_timer", - "//:ref_counted_ptr", - "//src/core:activity", "//src/core:arena", "//src/core:chaotic_good_client_transport", - "//src/core:event_engine_wakeup_scheduler", "//src/core:if", - "//src/core:join", "//src/core:loop", - "//src/core:map", - "//src/core:memory_quota", - "//src/core:pipe", - "//src/core:resource_quota", "//src/core:seq", - "//src/core:slice", "//src/core:slice_buffer", - "//test/core/event_engine/fuzzing_event_engine", - "//test/core/event_engine/fuzzing_event_engine:fuzzing_event_engine_proto", ], ) @@ -134,8 +155,8 @@ grpc_cc_test( uses_event_engine = False, uses_polling = False, deps = [ - "//:grpc", "//:grpc_public_hdrs", + "//:grpc_unsecure", "//:iomgr_timer", "//:ref_counted_ptr", "//src/core:activity", @@ -156,3 +177,36 @@ grpc_cc_test( "//test/core/event_engine/fuzzing_event_engine:fuzzing_event_engine_proto", ], ) + +grpc_cc_test( + name = "server_transport_test", + srcs = ["server_transport_test.cc"], + external_deps = [ + "absl/functional:any_invocable", + "absl/status", + "absl/status:statusor", + "absl/strings:str_format", + "absl/types:optional", + "gtest", + ], + language = "C++", + uses_event_engine = False, + uses_polling = False, + deps = [ + "mock_promise_endpoint", + "transport_test", + "//:grpc", + "//:grpc_public_hdrs", + "//:iomgr_timer", + "//:ref_counted_ptr", + "//src/core:arena", + "//src/core:chaotic_good_server_transport", + "//src/core:memory_quota", + "//src/core:resource_quota", + "//src/core:seq", + "//src/core:slice", + "//src/core:slice_buffer", + "//test/core/event_engine/fuzzing_event_engine", + "//test/core/event_engine/fuzzing_event_engine:fuzzing_event_engine_proto", + ], +) diff --git a/test/core/transport/chaotic_good/client_transport_error_test.cc b/test/core/transport/chaotic_good/client_transport_error_test.cc index 3b30c4ca330..295e060b809 100644 --- a/test/core/transport/chaotic_good/client_transport_error_test.cc +++ b/test/core/transport/chaotic_good/client_transport_error_test.cc @@ -12,37 +12,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/status/status.h" - -#include "src/core/ext/transport/chaotic_good/client_transport.h" -#include "src/core/lib/transport/promise_endpoint.h" -#include "src/core/lib/transport/transport.h" - -// IWYU pragma: no_include - #include -#include // IWYU pragma: keep +#include #include -#include // IWYU pragma: keep +#include #include #include -#include // IWYU pragma: keep +#include #include "absl/functional/any_invocable.h" -#include "absl/status/statusor.h" // IWYU pragma: keep -#include "absl/strings/str_format.h" // IWYU pragma: keep -#include "absl/types/optional.h" // IWYU pragma: keep +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/types/optional.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include #include -#include // IWYU pragma: keep +#include #include #include -#include // IWYU pragma: keep +#include +#include "src/core/ext/transport/chaotic_good/client_transport.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/promise/activity.h" @@ -56,14 +50,16 @@ #include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/slice/slice_buffer.h" -#include "src/core/lib/slice/slice_internal.h" // IWYU pragma: keep -#include "src/core/lib/transport/metadata_batch.h" // IWYU pragma: keep +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/promise_endpoint.h" +#include "src/core/lib/transport/transport.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" +using testing::AtMost; using testing::MockFunction; using testing::Return; -using testing::Sequence; using testing::StrictMock; using testing::WithArgs; @@ -98,333 +94,308 @@ class MockEndpoint GetLocalAddress, (), (const, override)); }; +struct MockPromiseEndpoint { + StrictMock* endpoint = new StrictMock(); + std::unique_ptr promise_endpoint = + std::make_unique( + std::unique_ptr>(endpoint), SliceBuffer()); +}; + +// Send messages from client to server. +auto SendClientToServerMessages(CallInitiator initiator, int num_messages) { + return Loop([initiator, num_messages]() mutable { + bool has_message = (num_messages > 0); + return If( + has_message, + Seq(initiator.PushMessage(GetContext()->MakePooled()), + [&num_messages]() -> LoopCtl { + --num_messages; + return Continue(); + }), + [initiator]() mutable -> LoopCtl { + initiator.FinishSends(); + return absl::OkStatus(); + }); + }); +} + +ClientMetadataHandle TestInitialMetadata() { + auto md = + GetContext()->MakePooled(GetContext()); + md->Set(HttpPathMetadata(), Slice::FromStaticString("/test")); + return md; +} + class ClientTransportTest : public ::testing::Test { - public: - ClientTransportTest() - : control_endpoint_ptr_(new StrictMock()), - data_endpoint_ptr_(new StrictMock()), - memory_allocator_( - ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator( - "test")), - control_endpoint_(*control_endpoint_ptr_), - data_endpoint_(*data_endpoint_ptr_), - event_engine_(std::make_shared< - grpc_event_engine::experimental::FuzzingEventEngine>( - []() { - grpc_timer_manager_set_threading(false); - grpc_event_engine::experimental::FuzzingEventEngine::Options - options; - return options; - }(), - fuzzing_event_engine::Actions())), - arena_(MakeScopedArena(initial_arena_size, &memory_allocator_)), - pipe_client_to_server_messages_(arena_.get()), - pipe_server_to_client_messages_(arena_.get()), - pipe_server_intial_metadata_(arena_.get()), - pipe_client_to_server_messages_second_(arena_.get()), - pipe_server_to_client_messages_second_(arena_.get()), - pipe_server_intial_metadata_second_(arena_.get()) {} - // Initial ClientTransport with read expecations - void InitialClientTransport() { - client_transport_ = std::make_unique( - std::make_unique( - std::unique_ptr(control_endpoint_ptr_), - SliceBuffer()), - std::make_unique( - std::unique_ptr(data_endpoint_ptr_), SliceBuffer()), - event_engine_); - } - // Send messages from client to server. - auto SendClientToServerMessages( - Pipe& pipe_client_to_server_messages, - int num_of_messages) { - return Loop([&pipe_client_to_server_messages, num_of_messages, - this]() mutable { - bool has_message = (num_of_messages > 0); - return If( - has_message, - Seq(pipe_client_to_server_messages.sender.Push( - arena_->MakePooled()), - [&num_of_messages]() -> LoopCtl { - num_of_messages--; - return Continue(); - }), - [&pipe_client_to_server_messages]() mutable -> LoopCtl { - pipe_client_to_server_messages.sender.Close(); - return absl::OkStatus(); - }); - }); - } - // Add stream into client transport, and expect return trailers of - // "grpc-status:code". - auto AddStream(CallArgs args) { - return client_transport_->AddStream(std::move(args)); + protected: + const std::shared_ptr& + event_engine() { + return event_engine_; } + MemoryAllocator* memory_allocator() { return &allocator_; } private: - MockEndpoint* control_endpoint_ptr_; - MockEndpoint* data_endpoint_ptr_; - size_t initial_arena_size = 1024; - MemoryAllocator memory_allocator_; - - protected: - MockEndpoint& control_endpoint_; - MockEndpoint& data_endpoint_; std::shared_ptr - event_engine_; - std::unique_ptr client_transport_; - ScopedArenaPtr arena_; - Pipe pipe_client_to_server_messages_; - Pipe pipe_server_to_client_messages_; - Pipe pipe_server_intial_metadata_; - // Added for mutliple streams tests. - Pipe pipe_client_to_server_messages_second_; - Pipe pipe_server_to_client_messages_second_; - Pipe pipe_server_intial_metadata_second_; - absl::AnyInvocable read_callback_; - Sequence control_endpoint_sequence_; - Sequence data_endpoint_sequence_; - // Added to verify received message payload. - const std::string message_ = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + event_engine_{ + std::make_shared( + []() { + grpc_timer_manager_set_threading(false); + grpc_event_engine::experimental::FuzzingEventEngine::Options + options; + return options; + }(), + fuzzing_event_engine::Actions())}; + MemoryAllocator allocator_ = MakeResourceQuota("test-quota") + ->memory_quota() + ->CreateMemoryAllocator("test-allocator"); }; TEST_F(ClientTransportTest, AddOneStreamWithWriteFailed) { + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; // Mock write failed and read is pending. - EXPECT_CALL(control_endpoint_, Write) + EXPECT_CALL(*control_endpoint.endpoint, Write) + .Times(AtMost(1)) .WillOnce( WithArgs<0>([](absl::AnyInvocable on_write) { on_write(absl::InternalError("control endpoint write failed.")); return false; })); - EXPECT_CALL(data_endpoint_, Write) + EXPECT_CALL(*data_endpoint.endpoint, Write) + .Times(AtMost(1)) .WillOnce( WithArgs<0>([](absl::AnyInvocable on_write) { on_write(absl::InternalError("data endpoint write failed.")); return false; })); - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence_) - .WillOnce(Return(false)); - InitialClientTransport(); - ClientMetadataHandle md; - auto args = CallArgs{std::move(md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages in client transport. - Join( - // Add first stream with call_args into client transport. - // Expect return trailers "grpc-status:unavailable". - AddStream(std::move(args)), - // Send messages to call_args.client_to_server_messages pipe, - // which will be eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_, 1)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret)->get(GrpcStatusMetadata()).value(), - GRPC_STATUS_UNAVAILABLE); - EXPECT_TRUE(std::get<1>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); + EXPECT_CALL(*control_endpoint.endpoint, Read).WillOnce(Return(false)); + auto transport = MakeOrphanable( + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + auto call = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call.handler)); + call.initiator.SpawnGuarded("test-send", [initiator = + call.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + StrictMock> on_done; + EXPECT_CALL(on_done, Call()); + call.initiator.SpawnInfallible( + "test-read", [&on_done, initiator = call.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_FALSE(md.ok()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), + GRPC_STATUS_UNAVAILABLE); + on_done.Call(); + return Empty{}; + }); + }); // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); } TEST_F(ClientTransportTest, AddOneStreamWithReadFailed) { + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; // Mock read failed. - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence_) + EXPECT_CALL(*control_endpoint.endpoint, Read) .WillOnce(WithArgs<0>( [](absl::AnyInvocable on_read) mutable { on_read(absl::InternalError("control endpoint read failed.")); // Return false to mock EventEngine read not finish. return false; })); - InitialClientTransport(); - ClientMetadataHandle md; - auto args = CallArgs{std::move(md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages in client transport. - Join( - // Add first stream with call_args into client transport. - // Expect return trailers "grpc-status:unavailable". - AddStream(std::move(args)), - // Send messages to call_args.client_to_server_messages pipe. - SendClientToServerMessages(pipe_client_to_server_messages_, 1)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret)->get(GrpcStatusMetadata()).value(), - GRPC_STATUS_UNAVAILABLE); - EXPECT_TRUE(std::get<1>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); + auto transport = MakeOrphanable( + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + auto call = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call.handler)); + call.initiator.SpawnGuarded("test-send", [initiator = + call.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + StrictMock> on_done; + EXPECT_CALL(on_done, Call()); + call.initiator.SpawnInfallible( + "test-read", [&on_done, initiator = call.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_FALSE(md.ok()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), + GRPC_STATUS_UNAVAILABLE); + on_done.Call(); + return Empty{}; + }); + }); // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); } TEST_F(ClientTransportTest, AddMultipleStreamWithWriteFailed) { // Mock write failed at first stream and second stream's write will fail too. - EXPECT_CALL(control_endpoint_, Write) - .Times(1) + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; + EXPECT_CALL(*control_endpoint.endpoint, Write) + .Times(AtMost(1)) .WillRepeatedly( WithArgs<0>([](absl::AnyInvocable on_write) { on_write(absl::InternalError("control endpoint write failed.")); return false; })); - EXPECT_CALL(data_endpoint_, Write) - .Times(1) + EXPECT_CALL(*data_endpoint.endpoint, Write) + .Times(AtMost(1)) .WillRepeatedly( WithArgs<0>([](absl::AnyInvocable on_write) { on_write(absl::InternalError("data endpoint write failed.")); return false; })); - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence_) - .WillOnce(Return(false)); - InitialClientTransport(); - ClientMetadataHandle first_stream_md; - ClientMetadataHandle second_stream_md; - auto first_stream_args = - CallArgs{std::move(first_stream_md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - auto second_stream_args = - CallArgs{std::move(second_stream_md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_second_.sender, - &pipe_client_to_server_messages_second_.receiver, - &pipe_server_to_client_messages_second_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages from client transport. - Join( - // Add first stream with call_args into client transport. - // Expect return trailers "grpc-status:unavailable". - AddStream(std::move(first_stream_args)), - // Send messages to first stream's - // call_args.client_to_server_messages pipe. - SendClientToServerMessages(pipe_client_to_server_messages_, 1)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret)->get(GrpcStatusMetadata()).value(), - GRPC_STATUS_UNAVAILABLE); - EXPECT_TRUE(std::get<1>(ret).ok()); - return absl::OkStatus(); - }, - Join( - // Add second stream with call_args into client transport. - // Expect return trailers "grpc-status:unavailable". - AddStream(std::move(second_stream_args)), - // Send messages to second stream's - // call_args.client_to_server_messages pipe. - SendClientToServerMessages(pipe_client_to_server_messages_second_, - 1)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret)->get(GrpcStatusMetadata()).value(), - GRPC_STATUS_UNAVAILABLE); - EXPECT_TRUE(std::get<1>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); + EXPECT_CALL(*control_endpoint.endpoint, Read).WillOnce(Return(false)); + auto transport = MakeOrphanable( + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + auto call1 = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call1.handler)); + auto call2 = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call2.handler)); + call1.initiator.SpawnGuarded("test-send-1", [initiator = + call1.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + call2.initiator.SpawnGuarded("test-send-2", [initiator = + call2.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + StrictMock> on_done1; + EXPECT_CALL(on_done1, Call()); + StrictMock> on_done2; + EXPECT_CALL(on_done2, Call()); + call1.initiator.SpawnInfallible( + "test-read-1", [&on_done1, initiator = call1.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_FALSE(md.ok()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done1](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), + GRPC_STATUS_UNAVAILABLE); + on_done1.Call(); + return Empty{}; + }); + }); + call2.initiator.SpawnInfallible( + "test-read-2", [&on_done2, initiator = call2.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_FALSE(md.ok()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done2](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), + GRPC_STATUS_UNAVAILABLE); + on_done2.Call(); + return Empty{}; + }); + }); // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); } TEST_F(ClientTransportTest, AddMultipleStreamWithReadFailed) { + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; // Mock read failed at first stream, and second stream's write will fail too. - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence_) + EXPECT_CALL(*control_endpoint.endpoint, Read) .WillOnce(WithArgs<0>( [](absl::AnyInvocable on_read) mutable { on_read(absl::InternalError("control endpoint read failed.")); // Return false to mock EventEngine read not finish. return false; })); - InitialClientTransport(); - ClientMetadataHandle first_stream_md; - ClientMetadataHandle second_stream_md; - auto first_stream_args = - CallArgs{std::move(first_stream_md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - auto second_stream_args = - CallArgs{std::move(second_stream_md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_second_.sender, - &pipe_client_to_server_messages_second_.receiver, - &pipe_server_to_client_messages_second_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages from client transport. - Join( - // Add first stream with call_args into client transport. - AddStream(std::move(first_stream_args)), - // Send messages to first stream's - // call_args.client_to_server_messages pipe, which will be - // eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_, 1)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret)->get(GrpcStatusMetadata()).value(), - GRPC_STATUS_UNAVAILABLE); - EXPECT_TRUE(std::get<1>(ret).ok()); - return absl::OkStatus(); - }, - Join( - // Add second stream with call_args into client transport. - AddStream(std::move(second_stream_args)), - // Send messages to second stream's - // call_args.client_to_server_messages pipe, which will be - // eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_second_, - 1)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret)->get(GrpcStatusMetadata()).value(), - GRPC_STATUS_UNAVAILABLE); - EXPECT_TRUE(std::get<1>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); + auto transport = MakeOrphanable( + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + auto call1 = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call1.handler)); + auto call2 = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call2.handler)); + call1.initiator.SpawnGuarded("test-send", [initiator = + call1.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + call2.initiator.SpawnGuarded("test-send", [initiator = + call2.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + StrictMock> on_done1; + EXPECT_CALL(on_done1, Call()); + StrictMock> on_done2; + EXPECT_CALL(on_done2, Call()); + call1.initiator.SpawnInfallible( + "test-read", [&on_done1, initiator = call1.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_FALSE(md.ok()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done1](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), + GRPC_STATUS_UNAVAILABLE); + on_done1.Call(); + return Empty{}; + }); + }); + call2.initiator.SpawnInfallible( + "test-read", [&on_done2, initiator = call2.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_FALSE(md.ok()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done2](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), + GRPC_STATUS_UNAVAILABLE); + on_done2.Call(); + return Empty{}; + }); + }); // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); } } // namespace testing diff --git a/test/core/transport/chaotic_good/client_transport_test.cc b/test/core/transport/chaotic_good/client_transport_test.cc index 86bbf578c29..551c6fd5762 100644 --- a/test/core/transport/chaotic_good/client_transport_test.cc +++ b/test/core/transport/chaotic_good/client_transport_test.cc @@ -14,461 +14,245 @@ #include "src/core/ext/transport/chaotic_good/client_transport.h" -// IWYU pragma: no_include - -#include // IWYU pragma: keep +#include +#include +#include #include -#include // IWYU pragma: keep +#include #include -#include // IWYU pragma: keep +#include #include "absl/functional/any_invocable.h" -#include "absl/status/statusor.h" // IWYU pragma: keep -#include "absl/strings/str_format.h" // IWYU pragma: keep -#include "absl/types/optional.h" // IWYU pragma: keep +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/types/optional.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include #include -#include // IWYU pragma: keep +#include #include #include -#include // IWYU pragma: keep +#include -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/timer_manager.h" -#include "src/core/lib/promise/activity.h" -#include "src/core/lib/promise/event_engine_wakeup_scheduler.h" #include "src/core/lib/promise/if.h" -#include "src/core/lib/promise/join.h" #include "src/core/lib/promise/loop.h" -#include "src/core/lib/promise/map.h" -#include "src/core/lib/promise/pipe.h" #include "src/core/lib/promise/seq.h" #include "src/core/lib/resource_quota/arena.h" -#include "src/core/lib/resource_quota/memory_quota.h" -#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/slice/slice_buffer.h" -#include "src/core/lib/slice/slice_internal.h" // IWYU pragma: keep -#include "src/core/lib/transport/metadata_batch.h" // IWYU pragma: keep -#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 "src/core/lib/transport/metadata_batch.h" +#include "test/core/transport/chaotic_good/mock_promise_endpoint.h" +#include "test/core/transport/chaotic_good/transport_test.h" using testing::MockFunction; using testing::Return; -using testing::Sequence; using testing::StrictMock; -using testing::WithArgs; + +using EventEngineSlice = grpc_event_engine::experimental::Slice; namespace grpc_core { namespace chaotic_good { namespace testing { -class MockEndpoint - : public grpc_event_engine::experimental::EventEngine::Endpoint { - public: - MOCK_METHOD( - bool, Read, - (absl::AnyInvocable on_read, - grpc_event_engine::experimental::SliceBuffer* buffer, - const grpc_event_engine::experimental::EventEngine::Endpoint::ReadArgs* - args), - (override)); +// Encoded string of header ":path: /demo.Service/Step". +const uint8_t kPathDemoServiceStep[] = { + 0x40, 0x05, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x12, 0x2f, + 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2f, 0x53, 0x74, 0x65, 0x70}; - MOCK_METHOD( - bool, Write, - (absl::AnyInvocable on_writable, - grpc_event_engine::experimental::SliceBuffer* data, - const grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs* - args), - (override)); +// Encoded string of trailer "grpc-status: 0". +const uint8_t kGrpcStatus0[] = {0x10, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x01, 0x30}; - MOCK_METHOD( - const grpc_event_engine::experimental::EventEngine::ResolvedAddress&, - GetPeerAddress, (), (const, override)); - MOCK_METHOD( - const grpc_event_engine::experimental::EventEngine::ResolvedAddress&, - GetLocalAddress, (), (const, override)); -}; +ClientMetadataHandle TestInitialMetadata() { + auto md = + GetContext()->MakePooled(GetContext()); + md->Set(HttpPathMetadata(), Slice::FromStaticString("/demo.Service/Step")); + return md; +} -class ClientTransportTest : public ::testing::Test { - public: - ClientTransportTest() - : control_endpoint_ptr_(new StrictMock()), - data_endpoint_ptr_(new StrictMock()), - memory_allocator_( - ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator( - "test")), - control_endpoint_(*control_endpoint_ptr_), - data_endpoint_(*data_endpoint_ptr_), - event_engine_(std::make_shared< - grpc_event_engine::experimental::FuzzingEventEngine>( - []() { - grpc_timer_manager_set_threading(false); - grpc_event_engine::experimental::FuzzingEventEngine::Options - options; - return options; - }(), - fuzzing_event_engine::Actions())), - arena_(MakeScopedArena(initial_arena_size, &memory_allocator_)), - pipe_client_to_server_messages_(arena_.get()), - pipe_server_to_client_messages_(arena_.get()), - pipe_server_intial_metadata_(arena_.get()), - pipe_client_to_server_messages_second_(arena_.get()), - pipe_server_to_client_messages_second_(arena_.get()), - pipe_server_intial_metadata_second_(arena_.get()) {} - // Expect how client transport will read from control/data endpoints with a - // test frame. - void AddReadExpectations(int num_of_streams) { - for (int i = 0; i < num_of_streams; i++) { - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence) - .WillOnce(WithArgs<0, 1>( - [this, i](absl::AnyInvocable on_read, - grpc_event_engine::experimental::SliceBuffer* - buffer) mutable { - // Construct test frame for EventEngine read: headers (15 - // bytes), message(16 bytes), message padding (48 byte), - // trailers (15 bytes). - const std::string frame_header = { - static_cast(0x80), // frame type = fragment - 0x03, // flag = has header + has trailer - 0x00, - 0x00, - static_cast(i + 1), // stream id = 1 - 0x00, - 0x00, - 0x00, - 0x1a, // header length = 26 - 0x00, - 0x00, - 0x00, - 0x08, // message length = 8 - 0x00, - 0x00, - 0x00, - 0x38, // message padding =56 - 0x00, - 0x00, - 0x00, - 0x0f, // trailer length = 15 - 0x00, - 0x00, - 0x00}; - // Schedule mock_endpoint to read buffer. - grpc_event_engine::experimental::Slice slice( - grpc_slice_from_cpp_string(frame_header)); - buffer->Append(std::move(slice)); - // Execute read callback later to control when read starts. - if (i == 0) { - read_callback_ = std::move(on_read); - // Return false to mock EventEngine read not finish. - return false; - } else { - return true; - } - })); - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence) - .WillOnce(WithArgs<1>( - [](grpc_event_engine::experimental::SliceBuffer* buffer) { - // Encoded string of header ":path: /demo.Service/Step". - const std::string header = { - 0x10, 0x05, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x12, 0x2f, - 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2f, 0x53, 0x74, 0x65, 0x70}; - // Encoded string of trailer "grpc-status: 0". - const std::string trailers = {0x10, 0x0b, 0x67, 0x72, 0x70, - 0x63, 0x2d, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x01, 0x30}; - // Schedule mock_endpoint to read buffer. - grpc_event_engine::experimental::Slice slice( - grpc_slice_from_cpp_string(header + trailers)); - buffer->Append(std::move(slice)); - return true; - })); - } - EXPECT_CALL(control_endpoint_, Read) - .InSequence(control_endpoint_sequence) - .WillOnce(Return(false)); - for (int i = 0; i < num_of_streams; i++) { - EXPECT_CALL(data_endpoint_, Read) - .InSequence(data_endpoint_sequence) - .WillOnce(WithArgs<1>( - [this](grpc_event_engine::experimental::SliceBuffer* buffer) { - const std::string message_padding = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - grpc_event_engine::experimental::Slice slice( - grpc_slice_from_cpp_string(message_padding + message_)); - buffer->Append(std::move(slice)); - return true; - })); - } - } - // Initial ClientTransport with read expecations - void InitialClientTransport(int num_of_streams) { - // Read expectaions need to be added before transport initialization since - // reader_ activity loop is started in ClientTransport initialization, - AddReadExpectations(num_of_streams); - client_transport_ = std::make_unique( - std::make_unique( - std::unique_ptr(control_endpoint_ptr_), - SliceBuffer()), - std::make_unique( - std::unique_ptr(data_endpoint_ptr_), SliceBuffer()), - event_engine_); - } - // Send messages from client to server. - auto SendClientToServerMessages( - Pipe& pipe_client_to_server_messages, - int num_of_messages) { - return Loop([&pipe_client_to_server_messages, num_of_messages, - this]() mutable { - bool has_message = (num_of_messages > 0); - return If( - has_message, - Seq(pipe_client_to_server_messages.sender.Push( - arena_->MakePooled()), - [&num_of_messages]() -> LoopCtl { - num_of_messages--; - return Continue(); - }), - [&pipe_client_to_server_messages]() mutable -> LoopCtl { - pipe_client_to_server_messages.sender.Close(); - return absl::OkStatus(); - }); - }); - } - // Add stream into client transport, and expect return trailers of - // "grpc-status:code". - auto AddStream(CallArgs args, const grpc_status_code trailers) { - return Seq(client_transport_->AddStream(std::move(args)), - [trailers](ServerMetadataHandle ret) { - // AddStream will finish with server trailers: - // "grpc-status:code". - EXPECT_EQ(ret->get(GrpcStatusMetadata()).value(), trailers); - return trailers; - }); - } - // Start read from control endpoints. - auto StartRead(const absl::Status& read_status) { - return [read_status, this] { - read_callback_(read_status); - return read_status; - }; - } - // Receive messages from server to client. - auto ReceiveServerToClientMessages( - Pipe& pipe_server_intial_metadata, - Pipe& pipe_server_to_client_messages) { - return Seq( - // Receive server initial metadata. - Map(pipe_server_intial_metadata.receiver.Next(), - [](NextResult r) { - // Expect value: ":path: /demo.Service/Step" - EXPECT_TRUE(r.has_value()); - EXPECT_EQ( - r.value()->get_pointer(HttpPathMetadata())->as_string_view(), - "/demo.Service/Step"); - return absl::OkStatus(); +// Send messages from client to server. +auto SendClientToServerMessages(CallInitiator initiator, int num_messages) { + return Loop([initiator, num_messages, i = 0]() mutable { + bool has_message = (i < num_messages); + return If( + has_message, + Seq(initiator.PushMessage(GetContext()->MakePooled( + SliceBuffer(Slice::FromCopiedString(std::to_string(i))), 0)), + [&i]() -> LoopCtl { + ++i; + return Continue(); }), - // Receive server to client messages. - Map(pipe_server_to_client_messages.receiver.Next(), - [this](NextResult r) { - EXPECT_TRUE(r.has_value()); - EXPECT_EQ(r.value()->payload()->JoinIntoString(), message_); - return absl::OkStatus(); - }), - [&pipe_server_intial_metadata, - &pipe_server_to_client_messages]() mutable { - // Close pipes after receive message. - pipe_server_to_client_messages.sender.Close(); - pipe_server_intial_metadata.sender.Close(); + [initiator]() mutable -> LoopCtl { + initiator.FinishSends(); return absl::OkStatus(); }); - } - - private: - MockEndpoint* control_endpoint_ptr_; - MockEndpoint* data_endpoint_ptr_; - size_t initial_arena_size = 1024; - MemoryAllocator memory_allocator_; - Sequence control_endpoint_sequence; - Sequence data_endpoint_sequence; - - protected: - MockEndpoint& control_endpoint_; - MockEndpoint& data_endpoint_; - std::shared_ptr - event_engine_; - std::unique_ptr client_transport_; - ScopedArenaPtr arena_; - Pipe pipe_client_to_server_messages_; - Pipe pipe_server_to_client_messages_; - Pipe pipe_server_intial_metadata_; - // Added for mutliple streams tests. - Pipe pipe_client_to_server_messages_second_; - Pipe pipe_server_to_client_messages_second_; - Pipe pipe_server_intial_metadata_second_; - absl::AnyInvocable read_callback_; - // Added to verify received message payload. - const std::string message_ = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; -}; - -TEST_F(ClientTransportTest, AddOneStream) { - InitialClientTransport(1); - ClientMetadataHandle md; - auto args = CallArgs{std::move(md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - EXPECT_CALL(control_endpoint_, Write).WillOnce(Return(true)); - EXPECT_CALL(data_endpoint_, Write).WillOnce(Return(true)); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages in client transport. - Join( - // Add first stream with call_args into client transport. - AddStream(std::move(args), GRPC_STATUS_OK), - // Start read from control endpoints. - StartRead(absl::OkStatus()), - // Send messages to call_args.client_to_server_messages pipe, - // which will be eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_, 1), - // Receive messages from control/data endpoints. - ReceiveServerToClientMessages(pipe_server_intial_metadata_, - pipe_server_to_client_messages_)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret), GRPC_STATUS_OK); - EXPECT_TRUE(std::get<1>(ret).ok()); - EXPECT_TRUE(std::get<2>(ret).ok()); - EXPECT_TRUE(std::get<3>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); - // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + }); } -TEST_F(ClientTransportTest, AddOneStreamMultipleMessages) { - InitialClientTransport(1); - ClientMetadataHandle md; - auto args = CallArgs{std::move(md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - EXPECT_CALL(control_endpoint_, Write).Times(3).WillRepeatedly(Return(true)); - EXPECT_CALL(data_endpoint_, Write).Times(3).WillRepeatedly(Return(true)); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages in client transport. - Join( - // Add first stream with call_args into client transport. - AddStream(std::move(args), GRPC_STATUS_OK), - // Start read from control endpoints. - StartRead(absl::OkStatus()), - // Send messages to call_args.client_to_server_messages pipe, - // which will be eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_, 3), - // Receive messages from control/data endpoints. - ReceiveServerToClientMessages(pipe_server_intial_metadata_, - pipe_server_to_client_messages_)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& ret) { - EXPECT_EQ(std::get<0>(ret), GRPC_STATUS_OK); - EXPECT_TRUE(std::get<1>(ret).ok()); - EXPECT_TRUE(std::get<2>(ret).ok()); - EXPECT_TRUE(std::get<3>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); +TEST_F(TransportTest, AddOneStream) { + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; + control_endpoint.ExpectRead( + {SerializedFrameHeader(FrameType::kFragment, 7, 1, 26, 8, 56, 15), + EventEngineSlice::FromCopiedBuffer(kPathDemoServiceStep, + sizeof(kPathDemoServiceStep)), + EventEngineSlice::FromCopiedBuffer(kGrpcStatus0, sizeof(kGrpcStatus0))}, + event_engine().get()); + data_endpoint.ExpectRead( + {EventEngineSlice::FromCopiedString("12345678"), Zeros(56)}, nullptr); + EXPECT_CALL(*control_endpoint.endpoint, Read) + .InSequence(control_endpoint.read_sequence) + .WillOnce(Return(false)); + auto transport = MakeOrphanable( + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + auto call = + MakeCall(event_engine().get(), Arena::Create(1024, memory_allocator())); + transport->StartCall(std::move(call.handler)); + StrictMock> on_done; + EXPECT_CALL(on_done, Call()); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 1, 1, + sizeof(kPathDemoServiceStep), 0, 0, 0), + EventEngineSlice::FromCopiedBuffer(kPathDemoServiceStep, + sizeof(kPathDemoServiceStep))}, + nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 2, 1, 0, 1, 63, 0)}, + nullptr); + data_endpoint.ExpectWrite( + {EventEngineSlice::FromCopiedString("0"), Zeros(63)}, nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 4, 1, 0, 0, 0, 0)}, nullptr); + call.initiator.SpawnGuarded("test-send", [initiator = + call.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 1)); + }); + call.initiator.SpawnInfallible( + "test-read", [&on_done, initiator = call.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_TRUE(md.ok()); + EXPECT_EQ( + md.value()->get_pointer(HttpPathMetadata())->as_string_view(), + "/demo.Service/Step"); + return Empty{}; + }, + initiator.PullMessage(), + [](NextResult msg) { + EXPECT_TRUE(msg.has_value()); + EXPECT_EQ(msg.value()->payload()->JoinIntoString(), "12345678"); + return Empty{}; + }, + initiator.PullMessage(), + [](NextResult msg) { + EXPECT_FALSE(msg.has_value()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), GRPC_STATUS_OK); + on_done.Call(); + return Empty{}; + }); + }); // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); } -TEST_F(ClientTransportTest, AddMultipleStreamsMultipleMessages) { - InitialClientTransport(2); - ClientMetadataHandle first_stream_md; - ClientMetadataHandle second_stream_md; - auto first_stream_args = - CallArgs{std::move(first_stream_md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_.sender, - &pipe_client_to_server_messages_.receiver, - &pipe_server_to_client_messages_.sender}; - auto second_stream_args = - CallArgs{std::move(second_stream_md), - ClientInitialMetadataOutstandingToken::Empty(), - nullptr, - &pipe_server_intial_metadata_second_.sender, - &pipe_client_to_server_messages_second_.receiver, - &pipe_server_to_client_messages_second_.sender}; - StrictMock> on_done; - EXPECT_CALL(on_done, Call(absl::OkStatus())); - EXPECT_CALL(control_endpoint_, Write).Times(6).WillRepeatedly(Return(true)); - EXPECT_CALL(data_endpoint_, Write).Times(6).WillRepeatedly(Return(true)); - auto activity = MakeActivity( - Seq( - // Concurrently: write and read messages from client transport. - Join( - // Add first stream with call_args into client transport. - AddStream(std::move(first_stream_args), GRPC_STATUS_OK), - // Start read from control endpoints. - StartRead(absl::OkStatus()), - // Send messages to first stream's - // call_args.client_to_server_messages pipe, which will be - // eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_, 3), - // Receive first stream's messages from control/data endpoints. - ReceiveServerToClientMessages(pipe_server_intial_metadata_, - pipe_server_to_client_messages_)), - Join( - // Add second stream with call_args into client transport. - AddStream(std::move(second_stream_args), GRPC_STATUS_OK), - // Send messages to second stream's - // call_args.client_to_server_messages pipe, which will be - // eventually sent to control/data endpoints. - SendClientToServerMessages(pipe_client_to_server_messages_second_, - 3), - // Receive second stream's messages from control/data endpoints. - ReceiveServerToClientMessages( - pipe_server_intial_metadata_second_, - pipe_server_to_client_messages_second_)), - // Once complete, verify successful sending and the received value. - [](const std::tuple& - ret) { - EXPECT_EQ(std::get<0>(ret), GRPC_STATUS_OK); - EXPECT_TRUE(std::get<1>(ret).ok()); - EXPECT_TRUE(std::get<2>(ret).ok()); - return absl::OkStatus(); - }), - EventEngineWakeupScheduler(event_engine_), - [&on_done](absl::Status status) { on_done.Call(std::move(status)); }); +TEST_F(TransportTest, AddOneStreamMultipleMessages) { + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; + control_endpoint.ExpectRead( + {SerializedFrameHeader(FrameType::kFragment, 3, 1, 26, 8, 56, 0), + EventEngineSlice::FromCopiedBuffer(kPathDemoServiceStep, + sizeof(kPathDemoServiceStep))}, + event_engine().get()); + control_endpoint.ExpectRead( + {SerializedFrameHeader(FrameType::kFragment, 6, 1, 0, 8, 56, 15), + EventEngineSlice::FromCopiedBuffer(kGrpcStatus0, sizeof(kGrpcStatus0))}, + event_engine().get()); + data_endpoint.ExpectRead( + {EventEngineSlice::FromCopiedString("12345678"), Zeros(56)}, nullptr); + data_endpoint.ExpectRead( + {EventEngineSlice::FromCopiedString("87654321"), Zeros(56)}, nullptr); + EXPECT_CALL(*control_endpoint.endpoint, Read) + .InSequence(control_endpoint.read_sequence) + .WillOnce(Return(false)); + auto transport = MakeOrphanable( + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + auto call = + MakeCall(event_engine().get(), Arena::Create(8192, memory_allocator())); + transport->StartCall(std::move(call.handler)); + StrictMock> on_done; + EXPECT_CALL(on_done, Call()); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 1, 1, + sizeof(kPathDemoServiceStep), 0, 0, 0), + EventEngineSlice::FromCopiedBuffer(kPathDemoServiceStep, + sizeof(kPathDemoServiceStep))}, + nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 2, 1, 0, 1, 63, 0)}, + nullptr); + data_endpoint.ExpectWrite( + {EventEngineSlice::FromCopiedString("0"), Zeros(63)}, nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 2, 1, 0, 1, 63, 0)}, + nullptr); + data_endpoint.ExpectWrite( + {EventEngineSlice::FromCopiedString("1"), Zeros(63)}, nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 4, 1, 0, 0, 0, 0)}, nullptr); + call.initiator.SpawnGuarded("test-send", [initiator = + call.initiator]() mutable { + return TrySeq(initiator.PushClientInitialMetadata(TestInitialMetadata()), + SendClientToServerMessages(initiator, 2)); + }); + call.initiator.SpawnInfallible( + "test-read", [&on_done, initiator = call.initiator]() mutable { + return Seq( + initiator.PullServerInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_TRUE(md.ok()); + EXPECT_EQ( + md.value()->get_pointer(HttpPathMetadata())->as_string_view(), + "/demo.Service/Step"); + return Empty{}; + }, + initiator.PullMessage(), + [](NextResult msg) { + EXPECT_TRUE(msg.has_value()); + EXPECT_EQ(msg.value()->payload()->JoinIntoString(), "12345678"); + return Empty{}; + }, + initiator.PullMessage(), + [](NextResult msg) { + EXPECT_TRUE(msg.has_value()); + EXPECT_EQ(msg.value()->payload()->JoinIntoString(), "87654321"); + return Empty{}; + }, + initiator.PullMessage(), + [](NextResult msg) { + EXPECT_FALSE(msg.has_value()); + return Empty{}; + }, + initiator.PullServerTrailingMetadata(), + [&on_done](ServerMetadataHandle md) { + EXPECT_EQ(md->get(GrpcStatusMetadata()).value(), GRPC_STATUS_OK); + on_done.Call(); + return Empty{}; + }); + }); // Wait until ClientTransport's internal activities to finish. - event_engine_->TickUntilIdle(); - event_engine_->UnsetGlobalHooks(); + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); } } // namespace testing diff --git a/test/core/transport/chaotic_good/frame_fuzzer.cc b/test/core/transport/chaotic_good/frame_fuzzer.cc index 57180ce1c20..03481560771 100644 --- a/test/core/transport/chaotic_good/frame_fuzzer.cc +++ b/test/core/transport/chaotic_good/frame_fuzzer.cc @@ -35,7 +35,9 @@ #include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/slice/slice_buffer.h" +#include "src/libfuzzer/libfuzzer_macro.h" #include "test/core/promise/test_context.h" +#include "test/core/transport/chaotic_good/frame_fuzzer.pb.h" bool squelch = false; @@ -51,10 +53,10 @@ template void AssertRoundTrips(const T& input, FrameType expected_frame_type) { HPackCompressor hpack_compressor; auto serialized = input.Serialize(&hpack_compressor); - GPR_ASSERT(serialized.Length() >= + GPR_ASSERT(serialized.control.Length() >= 24); // Initial output buffer size is 64 byte. uint8_t header_bytes[24]; - serialized.MoveFirstNBytesIntoBuffer(24, header_bytes); + serialized.control.MoveFirstNBytesIntoBuffer(24, header_bytes); auto header = FrameHeader::Parse(header_bytes); if (!header.ok()) { if (!squelch) { @@ -67,66 +69,69 @@ void AssertRoundTrips(const T& input, FrameType expected_frame_type) { T output; HPackParser hpack_parser; DeterministicBitGen bitgen; - auto deser = output.Deserialize(&hpack_parser, header.value(), - absl::BitGenRef(bitgen), serialized); + auto deser = + output.Deserialize(&hpack_parser, header.value(), absl::BitGenRef(bitgen), + GetContext(), std::move(serialized)); GPR_ASSERT(deser.ok()); GPR_ASSERT(output == input); } template -void FinishParseAndChecks(const FrameHeader& header, const uint8_t* data, - size_t size) { +void FinishParseAndChecks(const FrameHeader& header, BufferPair buffers) { T parsed; ExecCtx exec_ctx; // Initialized to get this_cpu() info in global_stat(). HPackParser hpack_parser; - SliceBuffer serialized; - serialized.Append(Slice::FromCopiedBuffer(data, size)); DeterministicBitGen bitgen; - auto deser = parsed.Deserialize(&hpack_parser, header, - absl::BitGenRef(bitgen), serialized); + auto deser = + parsed.Deserialize(&hpack_parser, header, absl::BitGenRef(bitgen), + GetContext(), std::move(buffers)); if (!deser.ok()) return; gpr_log(GPR_INFO, "Read frame: %s", parsed.ToString().c_str()); AssertRoundTrips(parsed, header.type); } -int Run(const uint8_t* data, size_t size) { - if (size < 1) return 0; - const bool is_server = (data[0] & 1) != 0; - size--; - data++; - if (size < 24) return 0; - auto r = FrameHeader::Parse(data); - if (!r.ok()) return 0; +void Run(const frame_fuzzer::Test& test) { + const uint8_t* control_data = + reinterpret_cast(test.control().data()); + size_t control_size = test.control().size(); + if (test.control().size() < 24) return; + auto r = FrameHeader::Parse(control_data); + if (!r.ok()) return; + if (test.data().size() != r->message_length) return; gpr_log(GPR_INFO, "Read frame header: %s", r->ToString().c_str()); - size -= 24; - data += 24; + control_data += 24; + control_size -= 24; MemoryAllocator memory_allocator = MemoryAllocator( ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator("test")); auto arena = MakeScopedArena(1024, &memory_allocator); TestContext ctx(arena.get()); + BufferPair buffers{ + SliceBuffer(Slice::FromCopiedBuffer(control_data, control_size)), + SliceBuffer( + Slice::FromCopiedBuffer(test.data().data(), test.data().size())), + }; switch (r->type) { default: - return 0; // We don't know how to parse this frame type. + return; // We don't know how to parse this frame type. case FrameType::kSettings: - FinishParseAndChecks(*r, data, size); + FinishParseAndChecks(*r, std::move(buffers)); break; case FrameType::kFragment: - if (is_server) { - FinishParseAndChecks(*r, data, size); + if (test.is_server()) { + FinishParseAndChecks(*r, std::move(buffers)); } else { - FinishParseAndChecks(*r, data, size); + FinishParseAndChecks(*r, std::move(buffers)); } break; case FrameType::kCancel: - FinishParseAndChecks(*r, data, size); + FinishParseAndChecks(*r, std::move(buffers)); break; } - return 0; } } // namespace chaotic_good } // namespace grpc_core -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - return grpc_core::chaotic_good::Run(data, size); +DEFINE_PROTO_FUZZER(const frame_fuzzer::Test& test) { + grpc_core::chaotic_good::Run(test); } diff --git a/test/core/transport/chaotic_good/frame_fuzzer.proto b/test/core/transport/chaotic_good/frame_fuzzer.proto new file mode 100644 index 00000000000..4ae8657e588 --- /dev/null +++ b/test/core/transport/chaotic_good/frame_fuzzer.proto @@ -0,0 +1,23 @@ +// 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. + +syntax = "proto3"; + +package frame_fuzzer; + +message Test { + bool is_server = 1; + bytes control = 2; + bytes data = 3; +} diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/5072496117219328 b/test/core/transport/chaotic_good/frame_fuzzer_corpus/5072496117219328 deleted file mode 100644 index 16d6e2f4fde2813246ca23877e80d539e834b3eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26 WcmcC+U}Ru0)K%dGQeXh&Lqq^0Hv&xn diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/5691448031772672 b/test/core/transport/chaotic_good/frame_fuzzer_corpus/5691448031772672 deleted file mode 100644 index 98e8a28385d868b52dc0209da655bed0b3deb36d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51 zcmY#rU}Rv(Q+)JKiUAB(8UiU*2B4sDdQm}gPEvewPG)LeNqlihVo5PjyqEz1DVhwJ diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-05c704327d21af2cc914de40e9d90d06f16ca0eb b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-05c704327d21af2cc914de40e9d90d06f16ca0eb deleted file mode 100644 index 0340f7dee017d1c99db70bcda61ea432dab08e71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74 ccmZQ*U}a!nbYQp!q{svR|J&OB|F82O0Ex&4LjV8( diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-5015de8c7cafb0b0ebbbfd28c29aedd5dbfdc03a b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-5015de8c7cafb0b0ebbbfd28c29aedd5dbfdc03a deleted file mode 100644 index 366c53025968158085863d58678bcd130f39ab81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66 ScmZQ*U}IolZ~$U5!G8cUK>@}9 diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-5a34978de8de6889ce913947a77f43f7cdea854c b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-5a34978de8de6889ce913947a77f43f7cdea854c deleted file mode 100644 index 74cb18c8e938ead8bc408336ba7cf8f0700045e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180 kcmZQ*U}9ikaA3H`0i<+*_$&j10+1R^K#f7?KazX20O4l@H2?qr diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-608f798a51077a8cdc45b11f335c079a81339fbe b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-608f798a51077a8cdc45b11f335c079a81339fbe deleted file mode 100644 index 2190f6bc1859843a84a8a46d0f0d1392e9995dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 mcmZQ*U}9ikbYQq9!2kgYP?~h=8v_Fi>ALXgc>EnA`yT*|4h5wE diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-6a002cb46eac21af4ab6fd74b61ff3ce26d96dff b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-6a002cb46eac21af4ab6fd74b61ff3ce26d96dff deleted file mode 100644 index 90739c7258095c3bd8026055b6e80dd9912dac00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 161 scmZQ*U}9ikaA3H`0i<+*_$&j10+1pBI6&0?iJnY?CZd$8G3fjU09rQ&H2?qr diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-7732ddd35a4deb8b7c9e462aaf8680986755e540 b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-7732ddd35a4deb8b7c9e462aaf8680986755e540 deleted file mode 100644 index 4d14b159ba6b64ea200a8dd65c0f9bfabb1a1972..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79 ccmZQ*U}a!nbYQr~$Uq7B|KHa3|9_qT0Fc@TKL7v# diff --git a/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-c171e98ebfe8b6485f9a4bea0b9cdfe683776675 b/test/core/transport/chaotic_good/frame_fuzzer_corpus/crash-c171e98ebfe8b6485f9a4bea0b9cdfe683776675 deleted file mode 100644 index 8fa12bd3aeaf54fed89e4f4e2f08bf1bc370ae21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70 VcmZQ Deserialize(std::vector data) { } TEST(FrameHeaderTest, SimpleSerialize) { - EXPECT_EQ(Serialize(FrameHeader{FrameType::kCancel, BitSet<2>::FromInt(0), + EXPECT_EQ(Serialize(FrameHeader{FrameType::kCancel, BitSet<3>::FromInt(0), 0x01020304, 0x05060708, 0x090a0b0c, 0x00000034, 0x0d0e0f10}), std::vector({ @@ -59,7 +59,7 @@ TEST(FrameHeaderTest, SimpleDeserialize) { 0x10, 0x0f, 0x0e, 0x0d // trailer_length })), absl::StatusOr(FrameHeader{ - FrameType::kCancel, BitSet<2>::FromInt(0), 0x01020304, + FrameType::kCancel, BitSet<3>::FromInt(0), 0x01020304, 0x05060708, 0x090a0b0c, 0x00000034, 0x0d0e0f10})); EXPECT_EQ(Deserialize(std::vector({ 0x81, 88, 88, 88, // type, flags @@ -75,19 +75,19 @@ TEST(FrameHeaderTest, SimpleDeserialize) { TEST(FrameHeaderTest, GetFrameLength) { EXPECT_EQ( - (FrameHeader{FrameType::kFragment, BitSet<2>::FromInt(3), 1, 0, 0, 0, 0}) + (FrameHeader{FrameType::kFragment, BitSet<3>::FromInt(5), 1, 0, 0, 0, 0}) .GetFrameLength(), 0); EXPECT_EQ( - (FrameHeader{FrameType::kFragment, BitSet<2>::FromInt(3), 1, 14, 0, 0, 0}) + (FrameHeader{FrameType::kFragment, BitSet<3>::FromInt(5), 1, 14, 0, 0, 0}) .GetFrameLength(), 14); - EXPECT_EQ((FrameHeader{FrameType::kFragment, BitSet<2>::FromInt(3), 1, 0, 14, + EXPECT_EQ((FrameHeader{FrameType::kFragment, BitSet<3>::FromInt(5), 1, 0, 14, 50, 0}) .GetFrameLength(), 0); EXPECT_EQ( - (FrameHeader{FrameType::kFragment, BitSet<2>::FromInt(3), 1, 0, 0, 0, 14}) + (FrameHeader{FrameType::kFragment, BitSet<3>::FromInt(5), 1, 0, 0, 0, 14}) .GetFrameLength(), 14); } diff --git a/test/core/transport/chaotic_good/frame_test.cc b/test/core/transport/chaotic_good/frame_test.cc index 00908f75a6e..15153a09b8d 100644 --- a/test/core/transport/chaotic_good/frame_test.cc +++ b/test/core/transport/chaotic_good/frame_test.cc @@ -21,27 +21,38 @@ #include "absl/status/statusor.h" #include "gtest/gtest.h" +#include "src/core/lib/resource_quota/memory_quota.h" +#include "src/core/lib/resource_quota/resource_quota.h" + namespace grpc_core { namespace chaotic_good { namespace { template -void AssertRoundTrips(const T input, FrameType expected_frame_type) { +void AssertRoundTrips(const T& input, FrameType expected_frame_type) { HPackCompressor hpack_compressor; - absl::BitGen bitgen; auto serialized = input.Serialize(&hpack_compressor); - EXPECT_GE(serialized.Length(), 24); + GPR_ASSERT(serialized.control.Length() >= + 24); // Initial output buffer size is 64 byte. uint8_t header_bytes[24]; - serialized.MoveFirstNBytesIntoBuffer(24, header_bytes); + serialized.control.MoveFirstNBytesIntoBuffer(24, header_bytes); auto header = FrameHeader::Parse(header_bytes); - EXPECT_TRUE(header.ok()) << header.status(); - EXPECT_EQ(header->type, expected_frame_type); + if (!header.ok()) { + Crash("Failed to parse header"); + } + GPR_ASSERT(header->type == expected_frame_type); T output; HPackParser hpack_parser; - auto deser = output.Deserialize(&hpack_parser, header.value(), - absl::BitGenRef(bitgen), serialized); - EXPECT_TRUE(deser.ok()) << deser; - EXPECT_EQ(output, input); + absl::BitGen bitgen; + MemoryAllocator allocator = MakeResourceQuota("test-quota") + ->memory_quota() + ->CreateMemoryAllocator("test-allocator"); + ScopedArenaPtr arena = MakeScopedArena(1024, &allocator); + auto deser = + output.Deserialize(&hpack_parser, header.value(), absl::BitGenRef(bitgen), + arena.get(), std::move(serialized)); + GPR_ASSERT(deser.ok()); + GPR_ASSERT(output == input); } TEST(FrameTest, SettingsFrameRoundTrips) { diff --git a/test/core/transport/chaotic_good/mock_promise_endpoint.cc b/test/core/transport/chaotic_good/mock_promise_endpoint.cc new file mode 100644 index 00000000000..9ba96e75804 --- /dev/null +++ b/test/core/transport/chaotic_good/mock_promise_endpoint.cc @@ -0,0 +1,89 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/core/transport/chaotic_good/mock_promise_endpoint.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +using EventEngineSlice = grpc_event_engine::experimental::Slice; +using grpc_event_engine::experimental::EventEngine; + +using testing::WithArgs; + +namespace grpc_core { +namespace chaotic_good { +namespace testing { + +void MockPromiseEndpoint::ExpectRead( + std::initializer_list slices_init, + EventEngine* schedule_on_event_engine) { + std::vector slices; + for (auto&& slice : slices_init) slices.emplace_back(slice.Copy()); + EXPECT_CALL(*endpoint, Read) + .InSequence(read_sequence) + .WillOnce(WithArgs<0, 1>( + [slices = std::move(slices), schedule_on_event_engine]( + absl::AnyInvocable on_read, + grpc_event_engine::experimental::SliceBuffer* buffer) mutable { + for (auto& slice : slices) { + buffer->Append(std::move(slice)); + } + if (schedule_on_event_engine != nullptr) { + schedule_on_event_engine->Run( + [on_read = std::move(on_read)]() mutable { + on_read(absl::OkStatus()); + }); + return false; + } else { + return true; + } + })); +} + +void MockPromiseEndpoint::ExpectWrite( + std::initializer_list slices, + EventEngine* schedule_on_event_engine) { + SliceBuffer expect; + for (auto&& slice : slices) { + expect.Append(grpc_event_engine::experimental::internal::SliceCast( + slice.Copy())); + } + EXPECT_CALL(*endpoint, Write) + .InSequence(write_sequence) + .WillOnce(WithArgs<0, 1>( + [expect = expect.JoinIntoString(), schedule_on_event_engine]( + absl::AnyInvocable on_writable, + grpc_event_engine::experimental::SliceBuffer* buffer) mutable { + SliceBuffer tmp; + grpc_slice_buffer_swap(buffer->c_slice_buffer(), + tmp.c_slice_buffer()); + EXPECT_EQ(tmp.JoinIntoString(), expect); + if (schedule_on_event_engine != nullptr) { + schedule_on_event_engine->Run( + [on_writable = std::move(on_writable)]() mutable { + on_writable(absl::OkStatus()); + }); + return false; + } else { + return true; + } + })); +} + +} // namespace testing +} // namespace chaotic_good +} // namespace grpc_core diff --git a/test/core/transport/chaotic_good/mock_promise_endpoint.h b/test/core/transport/chaotic_good/mock_promise_endpoint.h new file mode 100644 index 00000000000..c1534efb605 --- /dev/null +++ b/test/core/transport/chaotic_good/mock_promise_endpoint.h @@ -0,0 +1,77 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GRPC_TEST_CORE_TRANSPORT_CHAOTIC_GOOD_MOCK_PROMISE_ENDPOINT_H +#define GRPC_TEST_CORE_TRANSPORT_CHAOTIC_GOOD_MOCK_PROMISE_ENDPOINT_H + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +#include "src/core/lib/transport/promise_endpoint.h" + +namespace grpc_core { +namespace chaotic_good { +namespace testing { + +class MockEndpoint + : public grpc_event_engine::experimental::EventEngine::Endpoint { + public: + MOCK_METHOD( + bool, Read, + (absl::AnyInvocable on_read, + grpc_event_engine::experimental::SliceBuffer* buffer, + const grpc_event_engine::experimental::EventEngine::Endpoint::ReadArgs* + args), + (override)); + + MOCK_METHOD( + bool, Write, + (absl::AnyInvocable on_writable, + grpc_event_engine::experimental::SliceBuffer* data, + const grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs* + args), + (override)); + + MOCK_METHOD( + const grpc_event_engine::experimental::EventEngine::ResolvedAddress&, + GetPeerAddress, (), (const, override)); + MOCK_METHOD( + const grpc_event_engine::experimental::EventEngine::ResolvedAddress&, + GetLocalAddress, (), (const, override)); +}; + +struct MockPromiseEndpoint { + ::testing::StrictMock* endpoint = + new ::testing::StrictMock(); + std::unique_ptr promise_endpoint = + std::make_unique( + std::unique_ptr<::testing::StrictMock>(endpoint), + SliceBuffer()); + ::testing::Sequence read_sequence; + ::testing::Sequence write_sequence; + void ExpectRead( + std::initializer_list slices_init, + grpc_event_engine::experimental::EventEngine* schedule_on_event_engine); + void ExpectWrite( + std::initializer_list slices, + grpc_event_engine::experimental::EventEngine* schedule_on_event_engine); +}; + +} // namespace testing +} // namespace chaotic_good +} // namespace grpc_core + +#endif // GRPC_TEST_CORE_TRANSPORT_CHAOTIC_GOOD_MOCK_PROMISE_ENDPOINT_H diff --git a/test/core/transport/chaotic_good/server_transport_test.cc b/test/core/transport/chaotic_good/server_transport_test.cc new file mode 100644 index 00000000000..05a32a21817 --- /dev/null +++ b/test/core/transport/chaotic_good/server_transport_test.cc @@ -0,0 +1,198 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/core/ext/transport/chaotic_good/server_transport.h" + +#include +#include +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/types/optional.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/timer_manager.h" +#include "src/core/lib/promise/seq.h" +#include "src/core/lib/resource_quota/arena.h" +#include "src/core/lib/resource_quota/memory_quota.h" +#include "src/core/lib/resource_quota/resource_quota.h" +#include "src/core/lib/slice/slice_buffer.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/metadata_batch.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/transport/chaotic_good/mock_promise_endpoint.h" +#include "test/core/transport/chaotic_good/transport_test.h" + +using testing::_; +using testing::MockFunction; +using testing::Return; +using testing::StrictMock; +using testing::WithArgs; + +using EventEngineSlice = grpc_event_engine::experimental::Slice; + +namespace grpc_core { +namespace chaotic_good { +namespace testing { + +// Encoded string of header ":path: /demo.Service/Step". +const uint8_t kPathDemoServiceStep[] = { + 0x40, 0x05, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x12, 0x2f, + 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2f, 0x53, 0x74, 0x65, 0x70}; + +// Encoded string of trailer "grpc-status: 0". +const uint8_t kGrpcStatus0[] = {0x40, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x01, 0x30}; + +ServerMetadataHandle TestInitialMetadata() { + auto md = + GetContext()->MakePooled(GetContext()); + md->Set(HttpPathMetadata(), Slice::FromStaticString("/demo.Service/Step")); + return md; +} + +ServerMetadataHandle TestTrailingMetadata() { + auto md = + GetContext()->MakePooled(GetContext()); + md->Set(GrpcStatusMetadata(), GRPC_STATUS_OK); + return md; +} + +class MockAcceptor : public ServerTransport::Acceptor { + public: + virtual ~MockAcceptor() = default; + MOCK_METHOD(Arena*, CreateArena, (), (override)); + MOCK_METHOD(absl::StatusOr, CreateCall, + (ClientMetadata & client_initial_metadata, Arena* arena), + (override)); +}; + +TEST_F(TransportTest, ReadAndWriteOneMessage) { + MockPromiseEndpoint control_endpoint; + MockPromiseEndpoint data_endpoint; + StrictMock acceptor; + auto transport = MakeOrphanable( + CoreConfiguration::Get() + .channel_args_preconditioning() + .PreconditionChannelArgs(nullptr), + std::move(control_endpoint.promise_endpoint), + std::move(data_endpoint.promise_endpoint), event_engine()); + // Once we set the acceptor, expect to read some frames. + // We'll return a new request with a payload of "12345678". + control_endpoint.ExpectRead( + {SerializedFrameHeader(FrameType::kFragment, 7, 1, 26, 8, 56, 0), + EventEngineSlice::FromCopiedBuffer(kPathDemoServiceStep, + sizeof(kPathDemoServiceStep))}, + event_engine().get()); + data_endpoint.ExpectRead( + {EventEngineSlice::FromCopiedString("12345678"), Zeros(56)}, nullptr); + // Once that's read we'll create a new call + auto* call_arena = Arena::Create(1024, memory_allocator()); + CallInitiatorAndHandler call = MakeCall(event_engine().get(), call_arena); + EXPECT_CALL(acceptor, CreateArena).WillOnce(Return(call_arena)); + EXPECT_CALL(acceptor, CreateCall(_, call_arena)) + .WillOnce(WithArgs<0>([call_initiator = std::move(call.initiator)]( + ClientMetadata& client_initial_metadata) { + EXPECT_EQ(client_initial_metadata.get_pointer(HttpPathMetadata()) + ->as_string_view(), + "/demo.Service/Step"); + return call_initiator; + })); + transport->SetAcceptor(&acceptor); + StrictMock> on_done; + EXPECT_CALL(on_done, Call()); + EXPECT_CALL(*control_endpoint.endpoint, Read) + .InSequence(control_endpoint.read_sequence) + .WillOnce(Return(false)); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 1, 1, + sizeof(kPathDemoServiceStep), 0, 0, 0), + EventEngineSlice::FromCopiedBuffer(kPathDemoServiceStep, + sizeof(kPathDemoServiceStep))}, + nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 2, 1, 0, 8, 56, 0)}, + nullptr); + data_endpoint.ExpectWrite( + {EventEngineSlice::FromCopiedString("87654321"), Zeros(56)}, nullptr); + control_endpoint.ExpectWrite( + {SerializedFrameHeader(FrameType::kFragment, 4, 1, 0, 0, 0, + sizeof(kGrpcStatus0)), + EventEngineSlice::FromCopiedBuffer(kGrpcStatus0, sizeof(kGrpcStatus0))}, + nullptr); + call.handler.SpawnInfallible( + "test-io", [&on_done, handler = call.handler]() mutable { + return Seq( + handler.PullClientInitialMetadata(), + [](ValueOrFailure md) { + EXPECT_TRUE(md.ok()); + EXPECT_EQ( + md.value()->get_pointer(HttpPathMetadata())->as_string_view(), + "/demo.Service/Step"); + return Empty{}; + }, + handler.PullMessage(), + [](NextResult msg) { + EXPECT_TRUE(msg.has_value()); + EXPECT_EQ(msg.value()->payload()->JoinIntoString(), "12345678"); + return Empty{}; + }, + handler.PullMessage(), + [](NextResult msg) { + EXPECT_FALSE(msg.has_value()); + return Empty{}; + }, + handler.PushServerInitialMetadata(TestInitialMetadata()), + handler.PushMessage(Arena::MakePooled( + SliceBuffer(Slice::FromCopiedString("87654321")), 0)), + [handler]() mutable { + return handler.PushServerTrailingMetadata(TestTrailingMetadata()); + }, + [&on_done]() mutable { + on_done.Call(); + return Empty{}; + }); + }); + // Wait until ClientTransport's internal activities to finish. + event_engine()->TickUntilIdle(); + event_engine()->UnsetGlobalHooks(); +} + +} // namespace testing +} // namespace chaotic_good +} // namespace grpc_core + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + // Must call to create default EventEngine. + grpc_init(); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/core/transport/chaotic_good/transport_test.cc b/test/core/transport/chaotic_good/transport_test.cc new file mode 100644 index 00000000000..b43098fa7c7 --- /dev/null +++ b/test/core/transport/chaotic_good/transport_test.cc @@ -0,0 +1,60 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/core/transport/chaotic_good/transport_test.h" + +namespace grpc_core { +namespace chaotic_good { +namespace testing { + +grpc_event_engine::experimental::Slice SerializedFrameHeader( + FrameType type, uint8_t flags, uint32_t stream_id, uint32_t header_length, + uint32_t message_length, uint32_t message_padding, + uint32_t trailer_length) { + uint8_t buffer[24] = {static_cast(type), + flags, + 0, + 0, + static_cast(stream_id), + static_cast(stream_id >> 8), + static_cast(stream_id >> 16), + static_cast(stream_id >> 24), + static_cast(header_length), + static_cast(header_length >> 8), + static_cast(header_length >> 16), + static_cast(header_length >> 24), + static_cast(message_length), + static_cast(message_length >> 8), + static_cast(message_length >> 16), + static_cast(message_length >> 24), + static_cast(message_padding), + static_cast(message_padding >> 8), + static_cast(message_padding >> 16), + static_cast(message_padding >> 24), + static_cast(trailer_length), + static_cast(trailer_length >> 8), + static_cast(trailer_length >> 16), + static_cast(trailer_length >> 24)}; + return grpc_event_engine::experimental::Slice::FromCopiedBuffer(buffer, 24); +} + +grpc_event_engine::experimental::Slice Zeros(uint32_t length) { + std::string zeros(length, 0); + return grpc_event_engine::experimental::Slice::FromCopiedBuffer(zeros.data(), + length); +} + +} // namespace testing +} // namespace chaotic_good +} // namespace grpc_core diff --git a/test/core/transport/chaotic_good/transport_test.h b/test/core/transport/chaotic_good/transport_test.h new file mode 100644 index 00000000000..e70158bb8cf --- /dev/null +++ b/test/core/transport/chaotic_good/transport_test.h @@ -0,0 +1,67 @@ +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GRPC_TEST_CORE_TRANSPORT_CHAOTIC_GOOD_TRANSPORT_TEST_H +#define GRPC_TEST_CORE_TRANSPORT_CHAOTIC_GOOD_TRANSPORT_TEST_H + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "src/core/ext/transport/chaotic_good/frame.h" +#include "src/core/lib/iomgr/timer_manager.h" +#include "src/core/lib/resource_quota/memory_quota.h" +#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" + +namespace grpc_core { +namespace chaotic_good { +namespace testing { + +class TransportTest : public ::testing::Test { + protected: + const std::shared_ptr& + event_engine() { + return event_engine_; + } + + MemoryAllocator* memory_allocator() { return &allocator_; } + + private: + std::shared_ptr + event_engine_{ + std::make_shared( + []() { + grpc_timer_manager_set_threading(false); + grpc_event_engine::experimental::FuzzingEventEngine::Options + options; + return options; + }(), + fuzzing_event_engine::Actions())}; + MemoryAllocator allocator_ = MakeResourceQuota("test-quota") + ->memory_quota() + ->CreateMemoryAllocator("test-allocator"); +}; + +grpc_event_engine::experimental::Slice SerializedFrameHeader( + FrameType type, uint8_t flags, uint32_t stream_id, uint32_t header_length, + uint32_t message_length, uint32_t message_padding, uint32_t trailer_length); + +grpc_event_engine::experimental::Slice Zeros(uint32_t length); + +} // namespace testing +} // namespace chaotic_good +} // namespace grpc_core + +#endif // GRPC_TEST_CORE_TRANSPORT_CHAOTIC_GOOD_TRANSPORT_TEST_H diff --git a/test/core/transport/promise_endpoint_test.cc b/test/core/transport/promise_endpoint_test.cc index 760a2add6c7..e6ad3dd2713 100644 --- a/test/core/transport/promise_endpoint_test.cc +++ b/test/core/transport/promise_endpoint_test.cc @@ -524,6 +524,19 @@ TEST_F(PromiseEndpointTest, OneWriteSuccessful) { activity.Activate(); EXPECT_CALL(activity, WakeupRequested).Times(0); EXPECT_CALL(mock_endpoint_, Write).WillOnce(Return(true)); + auto promise = promise_endpoint_->Write( + SliceBuffer(Slice::FromCopiedString("hello world"))); + auto poll = promise(); + ASSERT_TRUE(poll.ready()); + EXPECT_EQ(absl::OkStatus(), poll.value()); + activity.Deactivate(); +} + +TEST_F(PromiseEndpointTest, EmptyWriteIsNoOp) { + MockActivity activity; + activity.Activate(); + EXPECT_CALL(activity, WakeupRequested).Times(0); + EXPECT_CALL(mock_endpoint_, Write).Times(0); auto promise = promise_endpoint_->Write(SliceBuffer()); auto poll = promise(); ASSERT_TRUE(poll.ready()); @@ -541,7 +554,8 @@ TEST_F(PromiseEndpointTest, OneWriteFailed) { on_write(this->kDummyErrorStatus); return false; })); - auto promise = promise_endpoint_->Write(SliceBuffer()); + auto promise = promise_endpoint_->Write( + SliceBuffer(Slice::FromCopiedString("hello world"))); auto poll = promise(); ASSERT_TRUE(poll.ready()); EXPECT_EQ(kDummyErrorStatus, poll.value()); @@ -564,7 +578,8 @@ TEST_F(PromiseEndpointTest, OnePendingWriteSuccessful) { // Return false to mock EventEngine write pending.. return false; })); - auto promise = promise_endpoint_->Write(SliceBuffer()); + auto promise = promise_endpoint_->Write( + SliceBuffer(Slice::FromCopiedString("hello world"))); EXPECT_TRUE(promise().pending()); // Mock EventEngine write succeeds, and promise resolves. write_callback(absl::OkStatus()); @@ -586,7 +601,8 @@ TEST_F(PromiseEndpointTest, OnePendingWriteFailed) { // Return false to mock EventEngine write pending.. return false; })); - auto promise = promise_endpoint_->Write(SliceBuffer()); + auto promise = promise_endpoint_->Write( + SliceBuffer(Slice::FromCopiedString("hello world"))); EXPECT_TRUE(promise().pending()); write_callback(kDummyErrorStatus); auto poll = promise(); @@ -807,8 +823,10 @@ TEST_F(MultiplePromiseEndpointTest, JoinWritesSuccessful) { EXPECT_CALL(on_done, Call(absl::OkStatus())); auto activity = MakeActivity( [this] { - return Seq(Join(this->first_promise_endpoint_.Write(SliceBuffer()), - this->second_promise_endpoint_.Write(SliceBuffer())), + return Seq(Join(this->first_promise_endpoint_.Write(SliceBuffer( + Slice::FromCopiedString("hello world"))), + this->second_promise_endpoint_.Write(SliceBuffer( + Slice::FromCopiedString("hello world")))), [](std::tuple ret) { // Both writes finish with `absl::OkStatus`. EXPECT_TRUE(std::get<0>(ret).ok()); @@ -832,8 +850,10 @@ TEST_F(MultiplePromiseEndpointTest, JoinOneWriteSuccessfulOneWriteFailed) { EXPECT_CALL(on_done, Call(kDummyErrorStatus)); auto activity = MakeActivity( [this] { - return Seq(Join(this->first_promise_endpoint_.Write(SliceBuffer()), - this->second_promise_endpoint_.Write(SliceBuffer())), + return Seq(Join(this->first_promise_endpoint_.Write(SliceBuffer( + Slice::FromCopiedString("hello world"))), + this->second_promise_endpoint_.Write(SliceBuffer( + Slice::FromCopiedString("hello world")))), [this](std::tuple ret) { // One write finish with `absl::OkStatus` and the other // write fails. @@ -864,8 +884,10 @@ TEST_F(MultiplePromiseEndpointTest, JoinWritesFailed) { EXPECT_CALL(on_done, Call(kDummyErrorStatus)); auto activity = MakeActivity( [this] { - return Seq(Join(this->first_promise_endpoint_.Write(SliceBuffer()), - this->second_promise_endpoint_.Write(SliceBuffer())), + return Seq(Join(this->first_promise_endpoint_.Write(SliceBuffer( + Slice::FromCopiedString("hello world"))), + this->second_promise_endpoint_.Write(SliceBuffer( + Slice::FromCopiedString("hello world")))), [this](std::tuple ret) { // Both writes fail with errors. EXPECT_FALSE(std::get<0>(ret).ok()); diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 7981a98a90b..ae3fad4bc33 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -9071,6 +9071,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": "server_transport_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From 9a7c0b5f5768bf4f843e7e500e224fe1b9dd1dac Mon Sep 17 00:00:00 2001 From: Xuan Wang Date: Mon, 8 Jan 2024 15:27:58 -0800 Subject: [PATCH 11/27] [Python Observability] Allow create call with registered method (#35002) Based on [OpenTelemetry Metrics gRFC](https://github.com/grpc/proposal/blob/master/A66-otel-stats.md#opentelemetry-metrics), we should recored unregistered RPC method name as `other`, this PR adds the ability to pass register method information when creating a call. We'll consider calls created using generated stubs as registered, note that this won't prevent user from setting `registered_method=True` when creating calls manually. This is also enabled for simple stub flow but **NOT enabled for AsyncIO**, we'll add that later when start working on AsyncIO Observability. Closes #35002 PiperOrigin-RevId: 596719121 --- examples/python/helloworld/helloworld_pb2.py | 27 ++--- examples/python/helloworld/helloworld_pb2.pyi | 14 +-- .../python/helloworld/helloworld_pb2_grpc.py | 104 +++++++++++++++++- src/compiler/python_generator.cc | 23 ++-- src/python/.gitignore | 4 +- src/python/grpcio/grpc/_channel.py | 75 ++++++++++++- .../grpc/_cython/_cygrpc/channel.pxd.pxi | 7 ++ .../grpc/_cython/_cygrpc/channel.pyx.pxi | 71 +++++++++--- .../grpcio/grpc/_cython/_cygrpc/grpc.pxi | 6 + src/python/grpcio/grpc/_interceptor.py | 36 +++++- src/python/grpcio/grpc/_simple_stubs.py | 81 +++++++++++--- src/python/grpcio/grpc/aio/_channel.py | 21 ++++ .../grpc_testing/_channel/_channel.py | 27 ++++- .../tests/channelz/_channelz_servicer_test.py | 17 ++- .../grpcio_tests/tests/csds/csds_test.py | 5 +- .../protoc_plugin/_python_plugin_test.py | 11 ++ .../tests/qps/benchmark_client.py | 9 +- .../tests/status/_grpc_status_test.py | 25 ++++- .../grpcio_tests/tests/unit/_abort_test.py | 20 +++- .../tests/unit/_auth_context_test.py | 20 +++- .../tests/unit/_channel_close_test.py | 35 ++++-- .../tests/unit/_compression_test.py | 20 +++- .../unit/_contextvars_propagation_test.py | 10 +- .../tests/unit/_dns_resolver_test.py | 5 +- .../tests/unit/_empty_message_test.py | 24 ++-- .../unit/_error_message_encoding_test.py | 5 +- .../tests/unit/_exit_scenarios.py | 20 +++- .../tests/unit/_interceptor_test.py | 8 +- .../tests/unit/_invalid_metadata_test.py | 9 +- .../tests/unit/_invocation_defects_test.py | 22 +++- .../tests/unit/_local_credentials_test.py | 14 ++- .../tests/unit/_metadata_code_details_test.py | 80 ++++++++------ .../tests/unit/_metadata_flags_test.py | 39 +++++-- .../grpcio_tests/tests/unit/_metadata_test.py | 16 ++- .../tests/unit/_reconnect_test.py | 5 +- .../tests/unit/_resource_exhausted_test.py | 20 +++- .../tests/unit/_rpc_test_helpers.py | 18 ++- .../tests/unit/_server_shutdown_scenarios.py | 5 +- .../tests/unit/_session_cache_test.py | 5 +- .../grpcio_tests/tests/unit/_signal_client.py | 24 ++-- .../tests/unit/_xds_credentials_test.py | 14 ++- .../tests_gevent/unit/close_channel_test.py | 2 + .../tests_py3_only/unit/_leak_test.py | 5 +- .../tests_py3_only/unit/_simple_stubs_test.py | 46 +++++++- 44 files changed, 839 insertions(+), 215 deletions(-) diff --git a/examples/python/helloworld/helloworld_pb2.py b/examples/python/helloworld/helloworld_pb2.py index f5b4f2d27dc..6ee31ad94a2 100644 --- a/examples/python/helloworld/helloworld_pb2.py +++ b/examples/python/helloworld/helloworld_pb2.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: helloworld.proto +# Protobuf Python Version: 4.25.0 """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -13,18 +14,18 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\xe4\x01\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x12K\n\x13SayHelloStreamReply\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x30\x01\x12L\n\x12SayHelloBidiStream\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW' - _HELLOREQUEST._serialized_start=32 - _HELLOREQUEST._serialized_end=60 - _HELLOREPLY._serialized_start=62 - _HELLOREPLY._serialized_end=91 - _GREETER._serialized_start=93 - _GREETER._serialized_end=166 + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW' + _globals['_HELLOREQUEST']._serialized_start=32 + _globals['_HELLOREQUEST']._serialized_end=60 + _globals['_HELLOREPLY']._serialized_start=62 + _globals['_HELLOREPLY']._serialized_end=91 + _globals['_GREETER']._serialized_start=94 + _globals['_GREETER']._serialized_end=322 # @@protoc_insertion_point(module_scope) diff --git a/examples/python/helloworld/helloworld_pb2.pyi b/examples/python/helloworld/helloworld_pb2.pyi index 8c4b5b22805..bf0bd395ad5 100644 --- a/examples/python/helloworld/helloworld_pb2.pyi +++ b/examples/python/helloworld/helloworld_pb2.pyi @@ -4,14 +4,14 @@ from typing import ClassVar as _ClassVar, Optional as _Optional DESCRIPTOR: _descriptor.FileDescriptor -class HelloReply(_message.Message): - __slots__ = ["message"] - MESSAGE_FIELD_NUMBER: _ClassVar[int] - message: str - def __init__(self, message: _Optional[str] = ...) -> None: ... - class HelloRequest(_message.Message): - __slots__ = ["name"] + __slots__ = ("name",) NAME_FIELD_NUMBER: _ClassVar[int] name: str def __init__(self, name: _Optional[str] = ...) -> None: ... + +class HelloReply(_message.Message): + __slots__ = ("message",) + MESSAGE_FIELD_NUMBER: _ClassVar[int] + message: str + def __init__(self, message: _Optional[str] = ...) -> None: ... diff --git a/examples/python/helloworld/helloworld_pb2_grpc.py b/examples/python/helloworld/helloworld_pb2_grpc.py index 47c186976e1..68bcfef1756 100644 --- a/examples/python/helloworld/helloworld_pb2_grpc.py +++ b/examples/python/helloworld/helloworld_pb2_grpc.py @@ -19,7 +19,17 @@ class GreeterStub(object): '/helloworld.Greeter/SayHello', request_serializer=helloworld__pb2.HelloRequest.SerializeToString, response_deserializer=helloworld__pb2.HelloReply.FromString, - ) + _registered_method=True) + self.SayHelloStreamReply = channel.unary_stream( + '/helloworld.Greeter/SayHelloStreamReply', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + _registered_method=True) + self.SayHelloBidiStream = channel.stream_stream( + '/helloworld.Greeter/SayHelloBidiStream', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + _registered_method=True) class GreeterServicer(object): @@ -33,6 +43,18 @@ class GreeterServicer(object): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def SayHelloStreamReply(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SayHelloBidiStream(self, request_iterator, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_GreeterServicer_to_server(servicer, server): rpc_method_handlers = { @@ -41,6 +63,16 @@ def add_GreeterServicer_to_server(servicer, server): request_deserializer=helloworld__pb2.HelloRequest.FromString, response_serializer=helloworld__pb2.HelloReply.SerializeToString, ), + 'SayHelloStreamReply': grpc.unary_stream_rpc_method_handler( + servicer.SayHelloStreamReply, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + 'SayHelloBidiStream': grpc.stream_stream_rpc_method_handler( + servicer.SayHelloBidiStream, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'helloworld.Greeter', rpc_method_handlers) @@ -63,8 +95,72 @@ class Greeter(object): wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/helloworld.Greeter/SayHello', + return grpc.experimental.unary_unary( + request, + target, + '/helloworld.Greeter/SayHello', helloworld__pb2.HelloRequest.SerializeToString, helloworld__pb2.HelloReply.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SayHelloStreamReply(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream( + request, + target, + '/helloworld.Greeter/SayHelloStreamReply', + helloworld__pb2.HelloRequest.SerializeToString, + helloworld__pb2.HelloReply.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SayHelloBidiStream(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_stream( + request_iterator, + target, + '/helloworld.Greeter/SayHelloBidiStream', + helloworld__pb2.HelloRequest.SerializeToString, + helloworld__pb2.HelloReply.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index 753fe1c8887..b7a3115bce0 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -467,7 +467,7 @@ bool PrivateGenerator::PrintStub( out->Print( method_dict, "response_deserializer=$ResponseModuleAndClass$.FromString,\n"); - out->Print(")\n"); + out->Print("_registered_method=True)\n"); } } } @@ -642,22 +642,27 @@ bool PrivateGenerator::PrintServiceClass( args_dict["ArityMethodName"] = arity_method_name; args_dict["PackageQualifiedService"] = package_qualified_service_name; args_dict["Method"] = method->name(); - out->Print(args_dict, - "return " - "grpc.experimental.$ArityMethodName$($RequestParameter$, " - "target, '/$PackageQualifiedService$/$Method$',\n"); + out->Print(args_dict, "return grpc.experimental.$ArityMethodName$(\n"); { IndentScope continuation_indent(out); StringMap serializer_dict; + out->Print(args_dict, "$RequestParameter$,\n"); + out->Print("target,\n"); + out->Print(args_dict, "'/$PackageQualifiedService$/$Method$',\n"); serializer_dict["RequestModuleAndClass"] = request_module_and_class; serializer_dict["ResponseModuleAndClass"] = response_module_and_class; out->Print(serializer_dict, "$RequestModuleAndClass$.SerializeToString,\n"); out->Print(serializer_dict, "$ResponseModuleAndClass$.FromString,\n"); - out->Print("options, channel_credentials,\n"); - out->Print( - "insecure, call_credentials, compression, wait_for_ready, " - "timeout, metadata)\n"); + out->Print("options,\n"); + out->Print("channel_credentials,\n"); + out->Print("insecure,\n"); + out->Print("call_credentials,\n"); + out->Print("compression,\n"); + out->Print("wait_for_ready,\n"); + out->Print("timeout,\n"); + out->Print("metadata,\n"); + out->Print("_registered_method=True)\n"); } } } diff --git a/src/python/.gitignore b/src/python/.gitignore index 095ab8bbae1..61363e8cb8d 100644 --- a/src/python/.gitignore +++ b/src/python/.gitignore @@ -1,4 +1,6 @@ -gens/ +build/ +grpc_root/ +third_party/ *_pb2.py *_pb2.pyi *_pb2_grpc.py diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 79c85a1b94c..bf29982ca65 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -24,6 +24,7 @@ import types from typing import ( Any, Callable, + Dict, Iterator, List, Optional, @@ -1054,6 +1055,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): _request_serializer: Optional[SerializingFunction] _response_deserializer: Optional[DeserializingFunction] _context: Any + _registered_call_handle: Optional[int] __slots__ = [ "_channel", @@ -1074,6 +1076,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): target: bytes, request_serializer: Optional[SerializingFunction], response_deserializer: Optional[DeserializingFunction], + _registered_call_handle: Optional[int], ): self._channel = channel self._managed_call = managed_call @@ -1082,6 +1085,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): self._request_serializer = request_serializer self._response_deserializer = response_deserializer self._context = cygrpc.build_census_context() + self._registered_call_handle = _registered_call_handle def _prepare( self, @@ -1153,6 +1157,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): ), ), self._context, + self._registered_call_handle, ) event = call.next_event() _handle_event(event, state, self._response_deserializer) @@ -1221,6 +1226,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): (operations,), event_handler, self._context, + self._registered_call_handle, ) return _MultiThreadedRendezvous( state, call, self._response_deserializer, deadline @@ -1234,6 +1240,7 @@ class _SingleThreadedUnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): _request_serializer: Optional[SerializingFunction] _response_deserializer: Optional[DeserializingFunction] _context: Any + _registered_call_handle: Optional[int] __slots__ = [ "_channel", @@ -1252,6 +1259,7 @@ class _SingleThreadedUnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): target: bytes, request_serializer: SerializingFunction, response_deserializer: DeserializingFunction, + _registered_call_handle: Optional[int], ): self._channel = channel self._method = method @@ -1259,6 +1267,7 @@ class _SingleThreadedUnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._request_serializer = request_serializer self._response_deserializer = response_deserializer self._context = cygrpc.build_census_context() + self._registered_call_handle = _registered_call_handle def __call__( # pylint: disable=too-many-locals self, @@ -1317,6 +1326,7 @@ class _SingleThreadedUnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): call_credentials, operations_and_tags, self._context, + self._registered_call_handle, ) return _SingleThreadedRendezvous( state, call, self._response_deserializer, deadline @@ -1331,6 +1341,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): _request_serializer: Optional[SerializingFunction] _response_deserializer: Optional[DeserializingFunction] _context: Any + _registered_call_handle: Optional[int] __slots__ = [ "_channel", @@ -1351,6 +1362,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): target: bytes, request_serializer: SerializingFunction, response_deserializer: DeserializingFunction, + _registered_call_handle: Optional[int], ): self._channel = channel self._managed_call = managed_call @@ -1359,6 +1371,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._request_serializer = request_serializer self._response_deserializer = response_deserializer self._context = cygrpc.build_census_context() + self._registered_call_handle = _registered_call_handle def __call__( # pylint: disable=too-many-locals self, @@ -1408,6 +1421,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): operations, _event_handler(state, self._response_deserializer), self._context, + self._registered_call_handle, ) return _MultiThreadedRendezvous( state, call, self._response_deserializer, deadline @@ -1422,6 +1436,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): _request_serializer: Optional[SerializingFunction] _response_deserializer: Optional[DeserializingFunction] _context: Any + _registered_call_handle: Optional[int] __slots__ = [ "_channel", @@ -1442,6 +1457,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): target: bytes, request_serializer: Optional[SerializingFunction], response_deserializer: Optional[DeserializingFunction], + _registered_call_handle: Optional[int], ): self._channel = channel self._managed_call = managed_call @@ -1450,6 +1466,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): self._request_serializer = request_serializer self._response_deserializer = response_deserializer self._context = cygrpc.build_census_context() + self._registered_call_handle = _registered_call_handle def _blocking( self, @@ -1482,6 +1499,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): augmented_metadata, initial_metadata_flags ), self._context, + self._registered_call_handle, ) _consume_request_iterator( request_iterator, state, call, self._request_serializer, None @@ -1572,6 +1590,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): ), event_handler, self._context, + self._registered_call_handle, ) _consume_request_iterator( request_iterator, @@ -1593,6 +1612,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): _request_serializer: Optional[SerializingFunction] _response_deserializer: Optional[DeserializingFunction] _context: Any + _registered_call_handle: Optional[int] __slots__ = [ "_channel", @@ -1611,8 +1631,9 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): managed_call: IntegratedCallFactory, method: bytes, target: bytes, - request_serializer: Optional[SerializingFunction] = None, - response_deserializer: Optional[DeserializingFunction] = None, + request_serializer: Optional[SerializingFunction], + response_deserializer: Optional[DeserializingFunction], + _registered_call_handle: Optional[int], ): self._channel = channel self._managed_call = managed_call @@ -1621,6 +1642,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): self._request_serializer = request_serializer self._response_deserializer = response_deserializer self._context = cygrpc.build_census_context() + self._registered_call_handle = _registered_call_handle def __call__( self, @@ -1662,6 +1684,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): operations, event_handler, self._context, + self._registered_call_handle, ) _consume_request_iterator( request_iterator, @@ -1751,7 +1774,8 @@ def _channel_managed_call_management(state: _ChannelCallState): credentials: Optional[cygrpc.CallCredentials], operations: Sequence[Sequence[cygrpc.Operation]], event_handler: UserTag, - context, + context: Any, + _registered_call_handle: Optional[int], ) -> cygrpc.IntegratedCall: """Creates a cygrpc.IntegratedCall. @@ -1768,6 +1792,8 @@ def _channel_managed_call_management(state: _ChannelCallState): event_handler: A behavior to call to handle the events resultant from the operations on the call. context: Context object for distributed tracing. + _registered_call_handle: An int representing the call handle of the + method, or None if the method is not registered. Returns: A cygrpc.IntegratedCall with which to conduct an RPC. """ @@ -1788,6 +1814,7 @@ def _channel_managed_call_management(state: _ChannelCallState): credentials, operations_and_tags, context, + _registered_call_handle, ) if state.managed_calls == 0: state.managed_calls = 1 @@ -2021,6 +2048,7 @@ class Channel(grpc.Channel): _call_state: _ChannelCallState _connectivity_state: _ChannelConnectivityState _target: str + _registered_call_handles: Dict[str, int] def __init__( self, @@ -2055,6 +2083,22 @@ class Channel(grpc.Channel): if cygrpc.g_gevent_activated: cygrpc.gevent_increment_channel_count() + def _get_registered_call_handle(self, method: str) -> int: + """ + Get the registered call handle for a method. + + This is a semi-private method. It is intended for use only by gRPC generated code. + + This method is not thread-safe. + + Args: + method: Required, the method name for the RPC. + + Returns: + The registered call handle pointer in the form of a Python Long. + """ + return self._channel.get_registered_call_handle(_common.encode(method)) + def _process_python_options( self, python_options: Sequence[ChannelArgumentType] ) -> None: @@ -2078,12 +2122,17 @@ class Channel(grpc.Channel): ) -> None: _unsubscribe(self._connectivity_state, callback) + # pylint: disable=arguments-differ def unary_unary( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.UnaryUnaryMultiCallable: + _registered_call_handle = None + if _registered_method: + _registered_call_handle = self._get_registered_call_handle(method) return _UnaryUnaryMultiCallable( self._channel, _channel_managed_call_management(self._call_state), @@ -2091,14 +2140,20 @@ class Channel(grpc.Channel): _common.encode(self._target), request_serializer, response_deserializer, + _registered_call_handle, ) + # pylint: disable=arguments-differ def unary_stream( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.UnaryStreamMultiCallable: + _registered_call_handle = None + if _registered_method: + _registered_call_handle = self._get_registered_call_handle(method) # NOTE(rbellevi): Benchmarks have shown that running a unary-stream RPC # on a single Python thread results in an appreciable speed-up. However, # due to slight differences in capability, the multi-threaded variant @@ -2110,6 +2165,7 @@ class Channel(grpc.Channel): _common.encode(self._target), request_serializer, response_deserializer, + _registered_call_handle, ) else: return _UnaryStreamMultiCallable( @@ -2119,14 +2175,20 @@ class Channel(grpc.Channel): _common.encode(self._target), request_serializer, response_deserializer, + _registered_call_handle, ) + # pylint: disable=arguments-differ def stream_unary( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.StreamUnaryMultiCallable: + _registered_call_handle = None + if _registered_method: + _registered_call_handle = self._get_registered_call_handle(method) return _StreamUnaryMultiCallable( self._channel, _channel_managed_call_management(self._call_state), @@ -2134,14 +2196,20 @@ class Channel(grpc.Channel): _common.encode(self._target), request_serializer, response_deserializer, + _registered_call_handle, ) + # pylint: disable=arguments-differ def stream_stream( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.StreamStreamMultiCallable: + _registered_call_handle = None + if _registered_method: + _registered_call_handle = self._get_registered_call_handle(method) return _StreamStreamMultiCallable( self._channel, _channel_managed_call_management(self._call_state), @@ -2149,6 +2217,7 @@ class Channel(grpc.Channel): _common.encode(self._target), request_serializer, response_deserializer, + _registered_call_handle, ) def _unsubscribe_all(self) -> None: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi index 6e5416a9e31..96d03e181b9 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi @@ -74,6 +74,13 @@ cdef class SegregatedCall: cdef class Channel: cdef _ChannelState _state + cdef dict _registered_call_handles # TODO(https://github.com/grpc/grpc/issues/15662): Eliminate this. cdef tuple _arguments + + +cdef class CallHandle: + + cdef void *c_call_handle + cdef object method diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index f6db36ebde1..dde3b166789 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -101,6 +101,25 @@ cdef class _ChannelState: self.connectivity_due = set() self.closed_reason = None +cdef class CallHandle: + + def __cinit__(self, _ChannelState channel_state, object method): + self.method = method + cpython.Py_INCREF(method) + # Note that since we always pass None for host, we set the + # second-to-last parameter of grpc_channel_register_call to a fixed + # NULL value. + self.c_call_handle = grpc_channel_register_call( + channel_state.c_channel, method, NULL, NULL) + + def __dealloc__(self): + cpython.Py_DECREF(self.method) + + @property + def call_handle(self): + return cpython.PyLong_FromVoidPtr(self.c_call_handle) + + cdef tuple _operate(grpc_call *c_call, object operations, object user_tag): cdef grpc_call_error c_call_error @@ -199,7 +218,7 @@ cdef void _call( grpc_completion_queue *c_completion_queue, on_success, int flags, method, host, object deadline, CallCredentials credentials, object operationses_and_user_tags, object metadata, - object context) except *: + object context, object registered_call_handle) except *: """Invokes an RPC. Args: @@ -226,6 +245,8 @@ cdef void _call( must be present in the first element of this value. metadata: The metadata for this call. context: Context object for distributed tracing. + registered_call_handle: An int representing the call handle of the method, or + None if the method is not registered. """ cdef grpc_slice method_slice cdef grpc_slice host_slice @@ -242,10 +263,16 @@ cdef void _call( else: host_slice = _slice_from_bytes(host) host_slice_ptr = &host_slice - call_state.c_call = grpc_channel_create_call( - channel_state.c_channel, NULL, flags, - c_completion_queue, method_slice, host_slice_ptr, - _timespec_from_time(deadline), NULL) + if registered_call_handle: + call_state.c_call = grpc_channel_create_registered_call( + channel_state.c_channel, NULL, flags, + c_completion_queue, cpython.PyLong_AsVoidPtr(registered_call_handle), + _timespec_from_time(deadline), NULL) + else: + call_state.c_call = grpc_channel_create_call( + channel_state.c_channel, NULL, flags, + c_completion_queue, method_slice, host_slice_ptr, + _timespec_from_time(deadline), NULL) grpc_slice_unref(method_slice) if host_slice_ptr: grpc_slice_unref(host_slice) @@ -309,7 +336,7 @@ cdef class IntegratedCall: cdef IntegratedCall _integrated_call( _ChannelState state, int flags, method, host, object deadline, object metadata, CallCredentials credentials, operationses_and_user_tags, - object context): + object context, object registered_call_handle): call_state = _CallState() def on_success(started_tags): @@ -318,7 +345,8 @@ cdef IntegratedCall _integrated_call( _call( state, call_state, state.c_call_completion_queue, on_success, flags, - method, host, deadline, credentials, operationses_and_user_tags, metadata, context) + method, host, deadline, credentials, operationses_and_user_tags, + metadata, context, registered_call_handle) return IntegratedCall(state, call_state) @@ -371,7 +399,7 @@ cdef class SegregatedCall: cdef SegregatedCall _segregated_call( _ChannelState state, int flags, method, host, object deadline, object metadata, CallCredentials credentials, operationses_and_user_tags, - object context): + object context, object registered_call_handle): cdef _CallState call_state = _CallState() cdef SegregatedCall segregated_call cdef grpc_completion_queue *c_completion_queue @@ -389,7 +417,7 @@ cdef SegregatedCall _segregated_call( _call( state, call_state, c_completion_queue, on_success, flags, method, host, deadline, credentials, operationses_and_user_tags, metadata, - context) + context, registered_call_handle) except: _destroy_c_completion_queue(c_completion_queue) raise @@ -486,6 +514,7 @@ cdef class Channel: else grpc_insecure_credentials_create()) self._state.c_channel = grpc_channel_create( target, c_channel_credentials, channel_args.c_args()) + self._registered_call_handles = {} grpc_channel_credentials_release(c_channel_credentials) def target(self): @@ -499,10 +528,10 @@ cdef class Channel: def integrated_call( self, int flags, method, host, object deadline, object metadata, CallCredentials credentials, operationses_and_tags, - object context = None): + object context = None, object registered_call_handle = None): return _integrated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags, context) + operationses_and_tags, context, registered_call_handle) def next_call_event(self): def on_success(tag): @@ -521,10 +550,10 @@ cdef class Channel: def segregated_call( self, int flags, method, host, object deadline, object metadata, CallCredentials credentials, operationses_and_tags, - object context = None): + object context = None, object registered_call_handle = None): return _segregated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags, context) + operationses_and_tags, context, registered_call_handle) def check_connectivity_state(self, bint try_to_connect): with self._state.condition: @@ -543,3 +572,19 @@ cdef class Channel: def close_on_fork(self, code, details): _close(self, code, details, True) + + def get_registered_call_handle(self, method): + """ + Get or registers a call handler for a method. + + This method is not thread-safe. + + Args: + method: Required, the method name for the RPC. + + Returns: + The registered call handle pointer in the form of a Python Long. + """ + if method not in self._registered_call_handles.keys(): + self._registered_call_handles[method] = CallHandle(self._state, method) + return self._registered_call_handles[method].call_handle diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index e1bc87d4abd..29149e9893a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -433,6 +433,12 @@ cdef extern from "grpc/grpc.h": grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, grpc_slice method, const grpc_slice *host, gpr_timespec deadline, void *reserved) nogil + void *grpc_channel_register_call( + grpc_channel *channel, const char *method, const char *host, void *reserved) nogil + grpc_call *grpc_channel_create_registered_call( + grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, + grpc_completion_queue *completion_queue, void* registered_call_handle, + gpr_timespec deadline, void *reserved) nogil grpc_connectivity_state grpc_channel_check_connectivity_state( grpc_channel *channel, int try_to_connect) nogil void grpc_channel_watch_connectivity_state( diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index 36bce4e3ba5..94abafebaa6 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -684,57 +684,85 @@ class _Channel(grpc.Channel): def unsubscribe(self, callback: Callable): self._channel.unsubscribe(callback) + # pylint: disable=arguments-differ def unary_unary( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.UnaryUnaryMultiCallable: + # pytype: disable=wrong-arg-count thunk = lambda m: self._channel.unary_unary( - m, request_serializer, response_deserializer + m, + request_serializer, + response_deserializer, + _registered_method, ) + # pytype: enable=wrong-arg-count if isinstance(self._interceptor, grpc.UnaryUnaryClientInterceptor): return _UnaryUnaryMultiCallable(thunk, method, self._interceptor) else: return thunk(method) + # pylint: disable=arguments-differ def unary_stream( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.UnaryStreamMultiCallable: + # pytype: disable=wrong-arg-count thunk = lambda m: self._channel.unary_stream( - m, request_serializer, response_deserializer + m, + request_serializer, + response_deserializer, + _registered_method, ) + # pytype: enable=wrong-arg-count if isinstance(self._interceptor, grpc.UnaryStreamClientInterceptor): return _UnaryStreamMultiCallable(thunk, method, self._interceptor) else: return thunk(method) + # pylint: disable=arguments-differ def stream_unary( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.StreamUnaryMultiCallable: + # pytype: disable=wrong-arg-count thunk = lambda m: self._channel.stream_unary( - m, request_serializer, response_deserializer + m, + request_serializer, + response_deserializer, + _registered_method, ) + # pytype: enable=wrong-arg-count if isinstance(self._interceptor, grpc.StreamUnaryClientInterceptor): return _StreamUnaryMultiCallable(thunk, method, self._interceptor) else: return thunk(method) + # pylint: disable=arguments-differ def stream_stream( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> grpc.StreamStreamMultiCallable: + # pytype: disable=wrong-arg-count thunk = lambda m: self._channel.stream_stream( - m, request_serializer, response_deserializer + m, + request_serializer, + response_deserializer, + _registered_method, ) + # pytype: enable=wrong-arg-count if isinstance(self._interceptor, grpc.StreamStreamClientInterceptor): return _StreamStreamMultiCallable(thunk, method, self._interceptor) else: diff --git a/src/python/grpcio/grpc/_simple_stubs.py b/src/python/grpcio/grpc/_simple_stubs.py index 7772860957b..3e88670aa08 100644 --- a/src/python/grpcio/grpc/_simple_stubs.py +++ b/src/python/grpcio/grpc/_simple_stubs.py @@ -159,7 +159,19 @@ class ChannelCache: channel_credentials: Optional[grpc.ChannelCredentials], insecure: bool, compression: Optional[grpc.Compression], - ) -> grpc.Channel: + method: str, + _registered_method: bool, + ) -> Tuple[grpc.Channel, Optional[int]]: + """Get a channel from cache or creates a new channel. + + This method also takes care of register method for channel, + which means we'll register a new call handle if we're calling a + non-registered method for an existing channel. + + Returns: + A tuple with two items. The first item is the channel, second item is + the call handle if the method is registered, None if it's not registered. + """ if insecure and channel_credentials: raise ValueError( "The insecure option is mutually exclusive with " @@ -176,18 +188,25 @@ class ChannelCache: key = (target, options, channel_credentials, compression) with self._lock: channel_data = self._mapping.get(key, None) + call_handle = None if channel_data is not None: channel = channel_data[0] + # Register a new call handle if we're calling a registered method for an + # existing channel and this method is not registered. + if _registered_method: + call_handle = channel._get_registered_call_handle(method) self._mapping.pop(key) self._mapping[key] = ( channel, datetime.datetime.now() + _EVICTION_PERIOD, ) - return channel + return channel, call_handle else: channel = _create_channel( target, options, channel_credentials, compression ) + if _registered_method: + call_handle = channel._get_registered_call_handle(method) self._mapping[key] = ( channel, datetime.datetime.now() + _EVICTION_PERIOD, @@ -197,7 +216,7 @@ class ChannelCache: or len(self._mapping) >= _MAXIMUM_CHANNELS ): self._condition.notify() - return channel + return channel, call_handle def _test_only_channel_count(self) -> int: with self._lock: @@ -205,6 +224,7 @@ class ChannelCache: @experimental_api +# pylint: disable=too-many-locals def unary_unary( request: RequestType, target: str, @@ -219,6 +239,7 @@ def unary_unary( wait_for_ready: Optional[bool] = None, timeout: Optional[float] = _DEFAULT_TIMEOUT, metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None, + _registered_method: Optional[bool] = False, ) -> ResponseType: """Invokes a unary-unary RPC without an explicitly specified channel. @@ -272,11 +293,17 @@ def unary_unary( Returns: The response to the RPC. """ - channel = ChannelCache.get().get_channel( - target, options, channel_credentials, insecure, compression + channel, method_handle = ChannelCache.get().get_channel( + target, + options, + channel_credentials, + insecure, + compression, + method, + _registered_method, ) multicallable = channel.unary_unary( - method, request_serializer, response_deserializer + method, request_serializer, response_deserializer, method_handle ) wait_for_ready = wait_for_ready if wait_for_ready is not None else True return multicallable( @@ -289,6 +316,7 @@ def unary_unary( @experimental_api +# pylint: disable=too-many-locals def unary_stream( request: RequestType, target: str, @@ -303,6 +331,7 @@ def unary_stream( wait_for_ready: Optional[bool] = None, timeout: Optional[float] = _DEFAULT_TIMEOUT, metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None, + _registered_method: Optional[bool] = False, ) -> Iterator[ResponseType]: """Invokes a unary-stream RPC without an explicitly specified channel. @@ -355,11 +384,17 @@ def unary_stream( Returns: An iterator of responses. """ - channel = ChannelCache.get().get_channel( - target, options, channel_credentials, insecure, compression + channel, method_handle = ChannelCache.get().get_channel( + target, + options, + channel_credentials, + insecure, + compression, + method, + _registered_method, ) multicallable = channel.unary_stream( - method, request_serializer, response_deserializer + method, request_serializer, response_deserializer, method_handle ) wait_for_ready = wait_for_ready if wait_for_ready is not None else True return multicallable( @@ -372,6 +407,7 @@ def unary_stream( @experimental_api +# pylint: disable=too-many-locals def stream_unary( request_iterator: Iterator[RequestType], target: str, @@ -386,6 +422,7 @@ def stream_unary( wait_for_ready: Optional[bool] = None, timeout: Optional[float] = _DEFAULT_TIMEOUT, metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None, + _registered_method: Optional[bool] = False, ) -> ResponseType: """Invokes a stream-unary RPC without an explicitly specified channel. @@ -438,11 +475,17 @@ def stream_unary( Returns: The response to the RPC. """ - channel = ChannelCache.get().get_channel( - target, options, channel_credentials, insecure, compression + channel, method_handle = ChannelCache.get().get_channel( + target, + options, + channel_credentials, + insecure, + compression, + method, + _registered_method, ) multicallable = channel.stream_unary( - method, request_serializer, response_deserializer + method, request_serializer, response_deserializer, method_handle ) wait_for_ready = wait_for_ready if wait_for_ready is not None else True return multicallable( @@ -455,6 +498,7 @@ def stream_unary( @experimental_api +# pylint: disable=too-many-locals def stream_stream( request_iterator: Iterator[RequestType], target: str, @@ -469,6 +513,7 @@ def stream_stream( wait_for_ready: Optional[bool] = None, timeout: Optional[float] = _DEFAULT_TIMEOUT, metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None, + _registered_method: Optional[bool] = False, ) -> Iterator[ResponseType]: """Invokes a stream-stream RPC without an explicitly specified channel. @@ -521,11 +566,17 @@ def stream_stream( Returns: An iterator of responses. """ - channel = ChannelCache.get().get_channel( - target, options, channel_credentials, insecure, compression + channel, method_handle = ChannelCache.get().get_channel( + target, + options, + channel_credentials, + insecure, + compression, + method, + _registered_method, ) multicallable = channel.stream_stream( - method, request_serializer, response_deserializer + method, request_serializer, response_deserializer, method_handle ) wait_for_ready = wait_for_ready if wait_for_ready is not None else True return multicallable( diff --git a/src/python/grpcio/grpc/aio/_channel.py b/src/python/grpcio/grpc/aio/_channel.py index bea64c27fa3..ea4de20965a 100644 --- a/src/python/grpcio/grpc/aio/_channel.py +++ b/src/python/grpcio/grpc/aio/_channel.py @@ -478,11 +478,20 @@ class Channel(_base_channel.Channel): await self.wait_for_state_change(state) state = self.get_state(try_to_connect=True) + # TODO(xuanwn): Implement this method after we have + # observability for Asyncio. + def _get_registered_call_handle(self, method: str) -> int: + pass + + # TODO(xuanwn): Implement _registered_method after we have + # observability for Asyncio. + # pylint: disable=arguments-differ,unused-argument def unary_unary( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> UnaryUnaryMultiCallable: return UnaryUnaryMultiCallable( self._channel, @@ -494,11 +503,15 @@ class Channel(_base_channel.Channel): self._loop, ) + # TODO(xuanwn): Implement _registered_method after we have + # observability for Asyncio. + # pylint: disable=arguments-differ,unused-argument def unary_stream( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> UnaryStreamMultiCallable: return UnaryStreamMultiCallable( self._channel, @@ -510,11 +523,15 @@ class Channel(_base_channel.Channel): self._loop, ) + # TODO(xuanwn): Implement _registered_method after we have + # observability for Asyncio. + # pylint: disable=arguments-differ,unused-argument def stream_unary( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> StreamUnaryMultiCallable: return StreamUnaryMultiCallable( self._channel, @@ -526,11 +543,15 @@ class Channel(_base_channel.Channel): self._loop, ) + # TODO(xuanwn): Implement _registered_method after we have + # observability for Asyncio. + # pylint: disable=arguments-differ,unused-argument def stream_stream( self, method: str, request_serializer: Optional[SerializingFunction] = None, response_deserializer: Optional[DeserializingFunction] = None, + _registered_method: Optional[bool] = False, ) -> StreamStreamMultiCallable: return StreamStreamMultiCallable( self._channel, diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_channel.py b/src/python/grpcio_testing/grpc_testing/_channel/_channel.py index 170533f63ea..3f12e1f4df8 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_channel.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_channel.py @@ -31,23 +31,42 @@ class TestingChannel(grpc_testing.Channel): def unsubscribe(self, callback): raise NotImplementedError() + def _get_registered_call_handle(self, method: str) -> int: + pass + def unary_unary( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): return _multi_callable.UnaryUnary(method, self._state) def unary_stream( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): return _multi_callable.UnaryStream(method, self._state) def stream_unary( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): return _multi_callable.StreamUnary(method, self._state) def stream_stream( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): return _multi_callable.StreamStream(method, self._state) diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py index 78333fc62c7..2379ab59a3c 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -99,16 +99,20 @@ class ChannelzServicerTest(unittest.TestCase): def _send_successful_unary_unary(self, idx): _, r = ( self._pairs[idx] - .channel.unary_unary(_SUCCESSFUL_UNARY_UNARY) + .channel.unary_unary( + _SUCCESSFUL_UNARY_UNARY, + _registered_method=True, + ) .with_call(_REQUEST) ) self.assertEqual(r.code(), grpc.StatusCode.OK) def _send_failed_unary_unary(self, idx): try: - self._pairs[idx].channel.unary_unary(_FAILED_UNARY_UNARY).with_call( - _REQUEST - ) + self._pairs[idx].channel.unary_unary( + _FAILED_UNARY_UNARY, + _registered_method=True, + ).with_call(_REQUEST) except grpc.RpcError: return else: @@ -117,7 +121,10 @@ class ChannelzServicerTest(unittest.TestCase): def _send_successful_stream_stream(self, idx): response_iterator = ( self._pairs[idx] - .channel.stream_stream(_SUCCESSFUL_STREAM_STREAM) + .channel.stream_stream( + _SUCCESSFUL_STREAM_STREAM, + _registered_method=True, + ) .__call__(iter([_REQUEST] * test_constants.STREAM_LENGTH)) ) cnt = 0 diff --git a/src/python/grpcio_tests/tests/csds/csds_test.py b/src/python/grpcio_tests/tests/csds/csds_test.py index c58cb5943d2..15bf4e8a49b 100644 --- a/src/python/grpcio_tests/tests/csds/csds_test.py +++ b/src/python/grpcio_tests/tests/csds/csds_test.py @@ -92,7 +92,10 @@ class TestCsds(unittest.TestCase): # Force the XdsClient to initialize and request a resource with self.assertRaises(grpc.RpcError) as rpc_error: - dummy_channel.unary_unary("")(b"", wait_for_ready=False, timeout=1) + dummy_channel.unary_unary( + "", + _registered_method=True, + )(b"", wait_for_ready=False, timeout=1) self.assertEqual( grpc.StatusCode.DEADLINE_EXCEEDED, rpc_error.exception.code() ) diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py index 9a6538cca35..c6e41b3ae8c 100644 --- a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py +++ b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py @@ -543,6 +543,17 @@ class PythonPluginTest(unittest.TestCase): ) service.server.stop(None) + def testRegisteredMethod(self): + """Tests that we're setting _registered_call_handle when create call using generated stub.""" + service = _CreateService() + self.assertTrue(service.stub.UnaryCall._registered_call_handle) + self.assertTrue( + service.stub.StreamingOutputCall._registered_call_handle + ) + self.assertTrue(service.stub.StreamingInputCall._registered_call_handle) + self.assertTrue(service.stub.FullDuplexCall._registered_call_handle) + service.server.stop(None) + @unittest.skipIf( sys.version_info[0] < 3 or sys.version_info[1] < 6, diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py index e5aafc4142f..9310f8a8c61 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_client.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py @@ -32,13 +32,16 @@ _TIMEOUT = 60 * 60 * 24 class GenericStub(object): def __init__(self, channel): self.UnaryCall = channel.unary_unary( - "/grpc.testing.BenchmarkService/UnaryCall" + "/grpc.testing.BenchmarkService/UnaryCall", + _registered_method=True, ) self.StreamingFromServer = channel.unary_stream( - "/grpc.testing.BenchmarkService/StreamingFromServer" + "/grpc.testing.BenchmarkService/StreamingFromServer", + _registered_method=True, ) self.StreamingCall = channel.stream_stream( - "/grpc.testing.BenchmarkService/StreamingCall" + "/grpc.testing.BenchmarkService/StreamingCall", + _registered_method=True, ) diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 2573e961f18..031bdbe4d53 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -138,7 +138,10 @@ class StatusTest(unittest.TestCase): self._channel.close() def test_status_ok(self): - _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) + _, call = self._channel.unary_unary( + _STATUS_OK, + _registered_method=True, + ).with_call(_REQUEST) # Succeed RPC doesn't have status status = rpc_status.from_call(call) @@ -146,7 +149,10 @@ class StatusTest(unittest.TestCase): def test_status_not_ok(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_STATUS_NOT_OK).with_call(_REQUEST) + self._channel.unary_unary( + _STATUS_NOT_OK, + _registered_method=True, + ).with_call(_REQUEST) rpc_error = exception_context.exception self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) @@ -156,7 +162,10 @@ class StatusTest(unittest.TestCase): def test_error_details(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST) + self._channel.unary_unary( + _ERROR_DETAILS, + _registered_method=True, + ).with_call(_REQUEST) rpc_error = exception_context.exception status = rpc_status.from_call(rpc_error) @@ -173,7 +182,10 @@ class StatusTest(unittest.TestCase): def test_code_message_validation(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_INCONSISTENT).with_call(_REQUEST) + self._channel.unary_unary( + _INCONSISTENT, + _registered_method=True, + ).with_call(_REQUEST) rpc_error = exception_context.exception self.assertEqual(rpc_error.code(), grpc.StatusCode.NOT_FOUND) @@ -182,7 +194,10 @@ class StatusTest(unittest.TestCase): def test_invalid_code(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_INVALID_CODE).with_call(_REQUEST) + self._channel.unary_unary( + _INVALID_CODE, + _registered_method=True, + ).with_call(_REQUEST) rpc_error = exception_context.exception self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) # Invalid status code exception raised during coversion diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py index 731bb741bec..46f48bd1cae 100644 --- a/src/python/grpcio_tests/tests/unit/_abort_test.py +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -107,7 +107,10 @@ class AbortTest(unittest.TestCase): def test_abort(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_ABORT)(_REQUEST) + self._channel.unary_unary( + _ABORT, + _registered_method=True, + )(_REQUEST) rpc_error = exception_context.exception self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) @@ -124,7 +127,10 @@ class AbortTest(unittest.TestCase): # Servicer will abort() after creating a local ref to do_not_leak_me. with self.assertRaises(grpc.RpcError): - self._channel.unary_unary(_ABORT)(_REQUEST) + self._channel.unary_unary( + _ABORT, + _registered_method=True, + )(_REQUEST) # Server may still have a stack frame reference to the exception even # after client sees error, so ensure server has shutdown. @@ -134,7 +140,10 @@ class AbortTest(unittest.TestCase): def test_abort_with_status(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_ABORT_WITH_STATUS)(_REQUEST) + self._channel.unary_unary( + _ABORT_WITH_STATUS, + _registered_method=True, + )(_REQUEST) rpc_error = exception_context.exception self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) @@ -143,7 +152,10 @@ class AbortTest(unittest.TestCase): def test_invalid_code(self): with self.assertRaises(grpc.RpcError) as exception_context: - self._channel.unary_unary(_INVALID_CODE)(_REQUEST) + self._channel.unary_unary( + _INVALID_CODE, + _registered_method=True, + )(_REQUEST) rpc_error = exception_context.exception self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) diff --git a/src/python/grpcio_tests/tests/unit/_auth_context_test.py b/src/python/grpcio_tests/tests/unit/_auth_context_test.py index 039c908c3e5..0e5e2017fba 100644 --- a/src/python/grpcio_tests/tests/unit/_auth_context_test.py +++ b/src/python/grpcio_tests/tests/unit/_auth_context_test.py @@ -78,7 +78,10 @@ class AuthContextTest(unittest.TestCase): server.start() with grpc.insecure_channel("localhost:%d" % port) as channel: - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + response = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + )(_REQUEST) server.stop(None) auth_data = pickle.loads(response) @@ -115,7 +118,10 @@ class AuthContextTest(unittest.TestCase): channel_creds, options=_PROPERTY_OPTIONS, ) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + response = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + )(_REQUEST) channel.close() server.stop(None) @@ -161,7 +167,10 @@ class AuthContextTest(unittest.TestCase): options=_PROPERTY_OPTIONS, ) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + response = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + )(_REQUEST) channel.close() server.stop(None) @@ -180,7 +189,10 @@ class AuthContextTest(unittest.TestCase): channel = grpc.secure_channel( "localhost:{}".format(port), channel_creds, options=channel_options ) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + response = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + )(_REQUEST) auth_data = pickle.loads(response) self.assertEqual( expect_ssl_session_reused, diff --git a/src/python/grpcio_tests/tests/unit/_channel_close_test.py b/src/python/grpcio_tests/tests/unit/_channel_close_test.py index 4e5f215af89..b2ba4e7c887 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_close_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_close_test.py @@ -123,7 +123,10 @@ class ChannelCloseTest(unittest.TestCase): def test_close_immediately_after_call_invocation(self): channel = grpc.insecure_channel("localhost:{}".format(self._port)) - multi_callable = channel.stream_stream(_STREAM_URI) + multi_callable = channel.stream_stream( + _STREAM_URI, + _registered_method=True, + ) request_iterator = _Pipe(()) response_iterator = multi_callable(request_iterator) channel.close() @@ -133,7 +136,10 @@ class ChannelCloseTest(unittest.TestCase): def test_close_while_call_active(self): channel = grpc.insecure_channel("localhost:{}".format(self._port)) - multi_callable = channel.stream_stream(_STREAM_URI) + multi_callable = channel.stream_stream( + _STREAM_URI, + _registered_method=True, + ) request_iterator = _Pipe((b"abc",)) response_iterator = multi_callable(request_iterator) next(response_iterator) @@ -146,7 +152,10 @@ class ChannelCloseTest(unittest.TestCase): with grpc.insecure_channel( "localhost:{}".format(self._port) ) as channel: # pylint: disable=bad-continuation - multi_callable = channel.stream_stream(_STREAM_URI) + multi_callable = channel.stream_stream( + _STREAM_URI, + _registered_method=True, + ) request_iterator = _Pipe((b"abc",)) response_iterator = multi_callable(request_iterator) next(response_iterator) @@ -158,7 +167,10 @@ class ChannelCloseTest(unittest.TestCase): with grpc.insecure_channel( "localhost:{}".format(self._port) ) as channel: # pylint: disable=bad-continuation - multi_callable = channel.stream_stream(_STREAM_URI) + multi_callable = channel.stream_stream( + _STREAM_URI, + _registered_method=True, + ) request_iterators = tuple( _Pipe((b"abc",)) for _ in range(test_constants.THREAD_CONCURRENCY) @@ -176,7 +188,10 @@ class ChannelCloseTest(unittest.TestCase): def test_many_concurrent_closes(self): channel = grpc.insecure_channel("localhost:{}".format(self._port)) - multi_callable = channel.stream_stream(_STREAM_URI) + multi_callable = channel.stream_stream( + _STREAM_URI, + _registered_method=True, + ) request_iterator = _Pipe((b"abc",)) response_iterator = multi_callable(request_iterator) next(response_iterator) @@ -203,10 +218,16 @@ class ChannelCloseTest(unittest.TestCase): with grpc.insecure_channel( "localhost:{}".format(self._port) ) as channel: - stream_multi_callable = channel.stream_stream(_STREAM_URI) + stream_multi_callable = channel.stream_stream( + _STREAM_URI, + _registered_method=True, + ) endless_iterator = itertools.repeat(b"abc") stream_response_iterator = stream_multi_callable(endless_iterator) - future = channel.unary_unary(_UNARY_URI).future(b"abc") + future = channel.unary_unary( + _UNARY_URI, + _registered_method=True, + ).future(b"abc") def on_done_callback(future): raise Exception("This should not cause a deadlock.") diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py index be2a528ea9b..9fdeca030d8 100644 --- a/src/python/grpcio_tests/tests/unit/_compression_test.py +++ b/src/python/grpcio_tests/tests/unit/_compression_test.py @@ -237,7 +237,10 @@ def _get_compression_ratios( def _unary_unary_client(channel, multicallable_kwargs, message): - multi_callable = channel.unary_unary(_UNARY_UNARY) + multi_callable = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) response = multi_callable(message, **multicallable_kwargs) if response != message: raise RuntimeError( @@ -246,7 +249,10 @@ def _unary_unary_client(channel, multicallable_kwargs, message): def _unary_stream_client(channel, multicallable_kwargs, message): - multi_callable = channel.unary_stream(_UNARY_STREAM) + multi_callable = channel.unary_stream( + _UNARY_STREAM, + _registered_method=True, + ) response_iterator = multi_callable(message, **multicallable_kwargs) for response in response_iterator: if response != message: @@ -256,7 +262,10 @@ def _unary_stream_client(channel, multicallable_kwargs, message): def _stream_unary_client(channel, multicallable_kwargs, message): - multi_callable = channel.stream_unary(_STREAM_UNARY) + multi_callable = channel.stream_unary( + _STREAM_UNARY, + _registered_method=True, + ) requests = (_REQUEST for _ in range(_STREAM_LENGTH)) response = multi_callable(requests, **multicallable_kwargs) if response != message: @@ -266,7 +275,10 @@ def _stream_unary_client(channel, multicallable_kwargs, message): def _stream_stream_client(channel, multicallable_kwargs, message): - multi_callable = channel.stream_stream(_STREAM_STREAM) + multi_callable = channel.stream_stream( + _STREAM_STREAM, + _registered_method=True, + ) request_prefix = str(0).encode("ascii") * 100 requests = ( request_prefix + str(i).encode("ascii") for i in range(_STREAM_LENGTH) diff --git a/src/python/grpcio_tests/tests/unit/_contextvars_propagation_test.py b/src/python/grpcio_tests/tests/unit/_contextvars_propagation_test.py index 6f3b601ceb2..5a23d5dc69e 100644 --- a/src/python/grpcio_tests/tests/unit/_contextvars_propagation_test.py +++ b/src/python/grpcio_tests/tests/unit/_contextvars_propagation_test.py @@ -116,7 +116,10 @@ class ContextVarsPropagationTest(unittest.TestCase): local_credentials, call_credentials ) with grpc.secure_channel(target, composite_credentials) as channel: - stub = channel.unary_unary(_UNARY_UNARY) + stub = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) response = stub(_REQUEST, wait_for_ready=True) self.assertEqual(_REQUEST, response) @@ -142,7 +145,10 @@ class ContextVarsPropagationTest(unittest.TestCase): with grpc.secure_channel( target, composite_credentials ) as channel: - stub = channel.unary_unary(_UNARY_UNARY) + stub = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) wait_group.done() wait_group.wait() for i in range(_RPC_COUNT): diff --git a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py index 62a95a02135..bcd7e6da849 100644 --- a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py +++ b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py @@ -55,7 +55,10 @@ class DNSResolverTest(unittest.TestCase): "loopback46.unittest.grpc.io:%d" % self._port ) as channel: self.assertEqual( - channel.unary_unary(_METHOD)( + channel.unary_unary( + _METHOD, + _registered_method=True, + )( _REQUEST, timeout=10, ), diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py index e2dc1594202..a303aa8b3e9 100644 --- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py +++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py @@ -96,25 +96,33 @@ class EmptyMessageTest(unittest.TestCase): self._channel.close() def testUnaryUnary(self): - response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST) + response = self._channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + )(_REQUEST) self.assertEqual(_RESPONSE, response) def testUnaryStream(self): - response_iterator = self._channel.unary_stream(_UNARY_STREAM)(_REQUEST) + response_iterator = self._channel.unary_stream( + _UNARY_STREAM, + _registered_method=True, + )(_REQUEST) self.assertSequenceEqual( [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator) ) def testStreamUnary(self): - response = self._channel.stream_unary(_STREAM_UNARY)( - iter([_REQUEST] * test_constants.STREAM_LENGTH) - ) + response = self._channel.stream_unary( + _STREAM_UNARY, + _registered_method=True, + )(iter([_REQUEST] * test_constants.STREAM_LENGTH)) self.assertEqual(_RESPONSE, response) def testStreamStream(self): - response_iterator = self._channel.stream_stream(_STREAM_STREAM)( - iter([_REQUEST] * test_constants.STREAM_LENGTH) - ) + response_iterator = self._channel.stream_stream( + _STREAM_STREAM, + _registered_method=True, + )(iter([_REQUEST] * test_constants.STREAM_LENGTH)) self.assertSequenceEqual( [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator) ) diff --git a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py index 4f07477fac9..334b7ed5a3a 100644 --- a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py +++ b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py @@ -73,7 +73,10 @@ class ErrorMessageEncodingTest(unittest.TestCase): def testMessageEncoding(self): for message in _UNICODE_ERROR_MESSAGES: - multi_callable = self._channel.unary_unary(_UNARY_UNARY) + multi_callable = self._channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) with self.assertRaises(grpc.RpcError) as cm: multi_callable(message.encode("utf-8")) diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py index c1f9816df08..1b7e2e5ac84 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py @@ -210,14 +210,20 @@ if __name__ == "__main__": method = TEST_TO_METHOD[args.scenario] if args.scenario == IN_FLIGHT_UNARY_UNARY_CALL: - multi_callable = channel.unary_unary(method) + multi_callable = channel.unary_unary( + method, + _registered_method=True, + ) future = multi_callable.future(REQUEST) result, call = multi_callable.with_call(REQUEST) elif ( args.scenario == IN_FLIGHT_UNARY_STREAM_CALL or args.scenario == IN_FLIGHT_PARTIAL_UNARY_STREAM_CALL ): - multi_callable = channel.unary_stream(method) + multi_callable = channel.unary_stream( + method, + _registered_method=True, + ) response_iterator = multi_callable(REQUEST) for response in response_iterator: pass @@ -225,7 +231,10 @@ if __name__ == "__main__": args.scenario == IN_FLIGHT_STREAM_UNARY_CALL or args.scenario == IN_FLIGHT_PARTIAL_STREAM_UNARY_CALL ): - multi_callable = channel.stream_unary(method) + multi_callable = channel.stream_unary( + method, + _registered_method=True, + ) future = multi_callable.future(infinite_request_iterator()) result, call = multi_callable.with_call( iter([REQUEST] * test_constants.STREAM_LENGTH) @@ -234,7 +243,10 @@ if __name__ == "__main__": args.scenario == IN_FLIGHT_STREAM_STREAM_CALL or args.scenario == IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL ): - multi_callable = channel.stream_stream(method) + multi_callable = channel.stream_stream( + method, + _registered_method=True, + ) response_iterator = multi_callable(infinite_request_iterator()) for response in response_iterator: pass diff --git a/src/python/grpcio_tests/tests/unit/_interceptor_test.py b/src/python/grpcio_tests/tests/unit/_interceptor_test.py index 9bbff1f6bee..72e299b5887 100644 --- a/src/python/grpcio_tests/tests/unit/_interceptor_test.py +++ b/src/python/grpcio_tests/tests/unit/_interceptor_test.py @@ -231,7 +231,7 @@ class _GenericHandler(grpc.GenericRpcHandler): def _unary_unary_multi_callable(channel): - return channel.unary_unary(_UNARY_UNARY) + return channel.unary_unary(_UNARY_UNARY, _registered_method=True) def _unary_stream_multi_callable(channel): @@ -239,6 +239,7 @@ def _unary_stream_multi_callable(channel): _UNARY_STREAM, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) @@ -247,11 +248,12 @@ def _stream_unary_multi_callable(channel): _STREAM_UNARY, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) def _stream_stream_multi_callable(channel): - return channel.stream_stream(_STREAM_STREAM) + return channel.stream_stream(_STREAM_STREAM, _registered_method=True) class _ClientCallDetails( @@ -562,7 +564,7 @@ class InterceptorTest(unittest.TestCase): self._record[:] = [] multi_callable = _unary_unary_multi_callable(channel) - multi_callable.with_call( + response, call = multi_callable.with_call( request, metadata=( ( diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py index a19966131c5..58d1e589fde 100644 --- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py @@ -32,7 +32,7 @@ _STREAM_STREAM = "/test/StreamStream" def _unary_unary_multi_callable(channel): - return channel.unary_unary(_UNARY_UNARY) + return channel.unary_unary(_UNARY_UNARY, _registered_method=True) def _unary_stream_multi_callable(channel): @@ -40,6 +40,7 @@ def _unary_stream_multi_callable(channel): _UNARY_STREAM, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) @@ -48,11 +49,15 @@ def _stream_unary_multi_callable(channel): _STREAM_UNARY, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) def _stream_stream_multi_callable(channel): - return channel.stream_stream(_STREAM_STREAM) + return channel.stream_stream( + _STREAM_STREAM, + _registered_method=True, + ) class InvalidMetadataTest(unittest.TestCase): diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py index b22ab016593..cb903e7b812 100644 --- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py +++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py @@ -219,7 +219,10 @@ class FailAfterFewIterationsCounter(object): def _unary_unary_multi_callable(channel): - return channel.unary_unary(_UNARY_UNARY) + return channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) def _unary_stream_multi_callable(channel): @@ -227,6 +230,7 @@ def _unary_stream_multi_callable(channel): _UNARY_STREAM, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) @@ -235,19 +239,29 @@ def _stream_unary_multi_callable(channel): _STREAM_UNARY, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) def _stream_stream_multi_callable(channel): - return channel.stream_stream(_STREAM_STREAM) + return channel.stream_stream( + _STREAM_STREAM, + _registered_method=True, + ) def _defective_handler_multi_callable(channel): - return channel.unary_unary(_DEFECTIVE_GENERIC_RPC_HANDLER) + return channel.unary_unary( + _DEFECTIVE_GENERIC_RPC_HANDLER, + _registered_method=True, + ) def _defective_nested_exception_handler_multi_callable(channel): - return channel.unary_unary(_UNARY_UNARY_NESTED_EXCEPTION) + return channel.unary_unary( + _UNARY_UNARY_NESTED_EXCEPTION, + _registered_method=True, + ) class InvocationDefectsTest(unittest.TestCase): diff --git a/src/python/grpcio_tests/tests/unit/_local_credentials_test.py b/src/python/grpcio_tests/tests/unit/_local_credentials_test.py index 165f6ca16eb..9c5b425eaf7 100644 --- a/src/python/grpcio_tests/tests/unit/_local_credentials_test.py +++ b/src/python/grpcio_tests/tests/unit/_local_credentials_test.py @@ -53,9 +53,10 @@ class LocalCredentialsTest(unittest.TestCase): ) as channel: self.assertEqual( b"abc", - channel.unary_unary("/test/method")( - b"abc", wait_for_ready=True - ), + channel.unary_unary( + "/test/method", + _registered_method=True, + )(b"abc", wait_for_ready=True), ) server.stop(None) @@ -77,9 +78,10 @@ class LocalCredentialsTest(unittest.TestCase): with grpc.secure_channel(server_addr, channel_creds) as channel: self.assertEqual( b"abc", - channel.unary_unary("/test/method")( - b"abc", wait_for_ready=True - ), + channel.unary_unary( + "/test/method", + _registered_method=True, + )(b"abc", wait_for_ready=True), ) server.stop(None) diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py index 3c530058dc3..320deb7e5f6 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py @@ -207,45 +207,53 @@ class MetadataCodeDetailsTest(unittest.TestCase): self._server.start() self._channel = grpc.insecure_channel("localhost:{}".format(port)) + unary_unary_method_name = "/".join( + ( + "", + _SERVICE, + _UNARY_UNARY, + ) + ) self._unary_unary = self._channel.unary_unary( - "/".join( - ( - "", - _SERVICE, - _UNARY_UNARY, - ) - ), + unary_unary_method_name, request_serializer=_REQUEST_SERIALIZER, response_deserializer=_RESPONSE_DESERIALIZER, + _registered_method=True, + ) + unary_stream_method_name = "/".join( + ( + "", + _SERVICE, + _UNARY_STREAM, + ) ) self._unary_stream = self._channel.unary_stream( - "/".join( - ( - "", - _SERVICE, - _UNARY_STREAM, - ) - ), + unary_stream_method_name, + _registered_method=True, + ) + stream_unary_method_name = "/".join( + ( + "", + _SERVICE, + _STREAM_UNARY, + ) ) self._stream_unary = self._channel.stream_unary( - "/".join( - ( - "", - _SERVICE, - _STREAM_UNARY, - ) - ), + stream_unary_method_name, + _registered_method=True, + ) + stream_stream_method_name = "/".join( + ( + "", + _SERVICE, + _STREAM_STREAM, + ) ) self._stream_stream = self._channel.stream_stream( - "/".join( - ( - "", - _SERVICE, - _STREAM_STREAM, - ) - ), + stream_stream_method_name, request_serializer=_REQUEST_SERIALIZER, response_deserializer=_RESPONSE_DESERIALIZER, + _registered_method=True, ) def tearDown(self): @@ -828,16 +836,18 @@ class InspectContextTest(unittest.TestCase): self._server.start() self._channel = grpc.insecure_channel("localhost:{}".format(port)) + unary_unary_method_name = "/".join( + ( + "", + _SERVICE, + _UNARY_UNARY, + ) + ) self._unary_unary = self._channel.unary_unary( - "/".join( - ( - "", - _SERVICE, - _UNARY_UNARY, - ) - ), + unary_unary_method_name, request_serializer=_REQUEST_SERIALIZER, response_deserializer=_RESPONSE_DESERIALIZER, + _registered_method=True, ) def tearDown(self): diff --git a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py index a67a496860f..2cd9ad9bd89 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py @@ -110,7 +110,10 @@ def create_phony_channel(): def perform_unary_unary_call(channel, wait_for_ready=None): - channel.unary_unary(_UNARY_UNARY).__call__( + channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ).__call__( _REQUEST, timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -118,7 +121,10 @@ def perform_unary_unary_call(channel, wait_for_ready=None): def perform_unary_unary_with_call(channel, wait_for_ready=None): - channel.unary_unary(_UNARY_UNARY).with_call( + channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ).with_call( _REQUEST, timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -126,7 +132,10 @@ def perform_unary_unary_with_call(channel, wait_for_ready=None): def perform_unary_unary_future(channel, wait_for_ready=None): - channel.unary_unary(_UNARY_UNARY).future( + channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ).future( _REQUEST, timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -134,7 +143,10 @@ def perform_unary_unary_future(channel, wait_for_ready=None): def perform_unary_stream_call(channel, wait_for_ready=None): - response_iterator = channel.unary_stream(_UNARY_STREAM).__call__( + response_iterator = channel.unary_stream( + _UNARY_STREAM, + _registered_method=True, + ).__call__( _REQUEST, timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -144,7 +156,10 @@ def perform_unary_stream_call(channel, wait_for_ready=None): def perform_stream_unary_call(channel, wait_for_ready=None): - channel.stream_unary(_STREAM_UNARY).__call__( + channel.stream_unary( + _STREAM_UNARY, + _registered_method=True, + ).__call__( iter([_REQUEST] * test_constants.STREAM_LENGTH), timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -152,7 +167,10 @@ def perform_stream_unary_call(channel, wait_for_ready=None): def perform_stream_unary_with_call(channel, wait_for_ready=None): - channel.stream_unary(_STREAM_UNARY).with_call( + channel.stream_unary( + _STREAM_UNARY, + _registered_method=True, + ).with_call( iter([_REQUEST] * test_constants.STREAM_LENGTH), timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -160,7 +178,10 @@ def perform_stream_unary_with_call(channel, wait_for_ready=None): def perform_stream_unary_future(channel, wait_for_ready=None): - channel.stream_unary(_STREAM_UNARY).future( + channel.stream_unary( + _STREAM_UNARY, + _registered_method=True, + ).future( iter([_REQUEST] * test_constants.STREAM_LENGTH), timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, @@ -168,7 +189,9 @@ def perform_stream_unary_future(channel, wait_for_ready=None): def perform_stream_stream_call(channel, wait_for_ready=None): - response_iterator = channel.stream_stream(_STREAM_STREAM).__call__( + response_iterator = channel.stream_stream( + _STREAM_STREAM, _registered_method=True + ).__call__( iter([_REQUEST] * test_constants.STREAM_LENGTH), timeout=test_constants.LONG_TIMEOUT, wait_for_ready=wait_for_ready, diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py index 7110177fa18..b9b7502972c 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py @@ -195,7 +195,9 @@ class MetadataTest(unittest.TestCase): self._channel.close() def testUnaryUnary(self): - multi_callable = self._channel.unary_unary(_UNARY_UNARY) + multi_callable = self._channel.unary_unary( + _UNARY_UNARY, _registered_method=True + ) unused_response, call = multi_callable.with_call( _REQUEST, metadata=_INVOCATION_METADATA ) @@ -211,7 +213,9 @@ class MetadataTest(unittest.TestCase): ) def testUnaryStream(self): - multi_callable = self._channel.unary_stream(_UNARY_STREAM) + multi_callable = self._channel.unary_stream( + _UNARY_STREAM, _registered_method=True + ) call = multi_callable(_REQUEST, metadata=_INVOCATION_METADATA) self.assertTrue( test_common.metadata_transmitted( @@ -227,7 +231,9 @@ class MetadataTest(unittest.TestCase): ) def testStreamUnary(self): - multi_callable = self._channel.stream_unary(_STREAM_UNARY) + multi_callable = self._channel.stream_unary( + _STREAM_UNARY, _registered_method=True + ) unused_response, call = multi_callable.with_call( iter([_REQUEST] * test_constants.STREAM_LENGTH), metadata=_INVOCATION_METADATA, @@ -244,7 +250,9 @@ class MetadataTest(unittest.TestCase): ) def testStreamStream(self): - multi_callable = self._channel.stream_stream(_STREAM_STREAM) + multi_callable = self._channel.stream_stream( + _STREAM_STREAM, _registered_method=True + ) call = multi_callable( iter([_REQUEST] * test_constants.STREAM_LENGTH), metadata=_INVOCATION_METADATA, diff --git a/src/python/grpcio_tests/tests/unit/_reconnect_test.py b/src/python/grpcio_tests/tests/unit/_reconnect_test.py index d412533251c..8d4fadaa3da 100644 --- a/src/python/grpcio_tests/tests/unit/_reconnect_test.py +++ b/src/python/grpcio_tests/tests/unit/_reconnect_test.py @@ -52,7 +52,10 @@ class ReconnectTest(unittest.TestCase): server.add_insecure_port(addr) server.start() channel = grpc.insecure_channel(addr) - multi_callable = channel.unary_unary(_UNARY_UNARY) + multi_callable = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) server.stop(None) # By default, the channel connectivity is checked every 5s diff --git a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py index 3fc04f06a18..93e72c84f07 100644 --- a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py +++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py @@ -149,7 +149,10 @@ class ResourceExhaustedTest(unittest.TestCase): self._channel.close() def testUnaryUnary(self): - multi_callable = self._channel.unary_unary(_UNARY_UNARY) + multi_callable = self._channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) futures = [] for _ in range(test_constants.THREAD_CONCURRENCY): futures.append(multi_callable.future(_REQUEST)) @@ -178,7 +181,10 @@ class ResourceExhaustedTest(unittest.TestCase): self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) def testUnaryStream(self): - multi_callable = self._channel.unary_stream(_UNARY_STREAM) + multi_callable = self._channel.unary_stream( + _UNARY_STREAM, + _registered_method=True, + ) calls = [] for _ in range(test_constants.THREAD_CONCURRENCY): calls.append(multi_callable(_REQUEST)) @@ -205,7 +211,10 @@ class ResourceExhaustedTest(unittest.TestCase): self.assertEqual(_RESPONSE, response) def testStreamUnary(self): - multi_callable = self._channel.stream_unary(_STREAM_UNARY) + multi_callable = self._channel.stream_unary( + _STREAM_UNARY, + _registered_method=True, + ) futures = [] request = iter([_REQUEST] * test_constants.STREAM_LENGTH) for _ in range(test_constants.THREAD_CONCURRENCY): @@ -236,7 +245,10 @@ class ResourceExhaustedTest(unittest.TestCase): self.assertEqual(_RESPONSE, multi_callable(request)) def testStreamStream(self): - multi_callable = self._channel.stream_stream(_STREAM_STREAM) + multi_callable = self._channel.stream_stream( + _STREAM_STREAM, + _registered_method=True, + ) calls = [] request = iter([_REQUEST] * test_constants.STREAM_LENGTH) for _ in range(test_constants.THREAD_CONCURRENCY): diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test_helpers.py b/src/python/grpcio_tests/tests/unit/_rpc_test_helpers.py index 1027be1c677..d85eb30c8e7 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test_helpers.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test_helpers.py @@ -277,7 +277,10 @@ class _GenericHandler(grpc.GenericRpcHandler): def unary_unary_multi_callable(channel): - return channel.unary_unary(_UNARY_UNARY) + return channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + ) def unary_stream_multi_callable(channel): @@ -285,6 +288,7 @@ def unary_stream_multi_callable(channel): _UNARY_STREAM, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) @@ -293,6 +297,7 @@ def unary_stream_non_blocking_multi_callable(channel): _UNARY_STREAM_NON_BLOCKING, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) @@ -301,15 +306,22 @@ def stream_unary_multi_callable(channel): _STREAM_UNARY, request_serializer=_SERIALIZE_REQUEST, response_deserializer=_DESERIALIZE_RESPONSE, + _registered_method=True, ) def stream_stream_multi_callable(channel): - return channel.stream_stream(_STREAM_STREAM) + return channel.stream_stream( + _STREAM_STREAM, + _registered_method=True, + ) def stream_stream_non_blocking_multi_callable(channel): - return channel.stream_stream(_STREAM_STREAM_NON_BLOCKING) + return channel.stream_stream( + _STREAM_STREAM_NON_BLOCKING, + _registered_method=True, + ) class BaseRPCTest(object): diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index 9190f108f7b..34d51fd72ec 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -81,7 +81,10 @@ def run_test(args): thread.start() port = port_queue.get() channel = grpc.insecure_channel("localhost:%d" % port) - multi_callable = channel.unary_unary(FORK_EXIT) + multi_callable = channel.unary_unary( + FORK_EXIT, + _registered_method=True, + ) result, call = multi_callable.with_call(REQUEST, wait_for_ready=True) os.wait() else: diff --git a/src/python/grpcio_tests/tests/unit/_session_cache_test.py b/src/python/grpcio_tests/tests/unit/_session_cache_test.py index acf671d1ca9..e4bc64f7d11 100644 --- a/src/python/grpcio_tests/tests/unit/_session_cache_test.py +++ b/src/python/grpcio_tests/tests/unit/_session_cache_test.py @@ -77,7 +77,10 @@ class SSLSessionCacheTest(unittest.TestCase): channel = grpc.secure_channel( "localhost:{}".format(port), channel_creds, options=channel_options ) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + response = channel.unary_unary( + _UNARY_UNARY, + _registered_method=True, + )(_REQUEST) auth_data = pickle.loads(response) self.assertEqual( expect_ssl_session_reused, diff --git a/src/python/grpcio_tests/tests/unit/_signal_client.py b/src/python/grpcio_tests/tests/unit/_signal_client.py index 56563c20075..34c3da0c933 100644 --- a/src/python/grpcio_tests/tests/unit/_signal_client.py +++ b/src/python/grpcio_tests/tests/unit/_signal_client.py @@ -53,7 +53,10 @@ def main_unary(server_target): """Initiate a unary RPC to be interrupted by a SIGINT.""" global per_process_rpc_future # pylint: disable=global-statement with grpc.insecure_channel(server_target) as channel: - multicallable = channel.unary_unary(UNARY_UNARY) + multicallable = channel.unary_unary( + UNARY_UNARY, + _registered_method=True, + ) signal.signal(signal.SIGINT, handle_sigint) per_process_rpc_future = multicallable.future( _MESSAGE, wait_for_ready=True @@ -67,9 +70,10 @@ def main_streaming(server_target): global per_process_rpc_future # pylint: disable=global-statement with grpc.insecure_channel(server_target) as channel: signal.signal(signal.SIGINT, handle_sigint) - per_process_rpc_future = channel.unary_stream(UNARY_STREAM)( - _MESSAGE, wait_for_ready=True - ) + per_process_rpc_future = channel.unary_stream( + UNARY_STREAM, + _registered_method=True, + )(_MESSAGE, wait_for_ready=True) for result in per_process_rpc_future: pass assert False, _ASSERTION_MESSAGE @@ -79,7 +83,10 @@ def main_unary_with_exception(server_target): """Initiate a unary RPC with a signal handler that will raise.""" channel = grpc.insecure_channel(server_target) try: - channel.unary_unary(UNARY_UNARY)(_MESSAGE, wait_for_ready=True) + channel.unary_unary( + UNARY_UNARY, + _registered_method=True, + )(_MESSAGE, wait_for_ready=True) except KeyboardInterrupt: sys.stderr.write("Running signal handler.\n") sys.stderr.flush() @@ -92,9 +99,10 @@ def main_streaming_with_exception(server_target): """Initiate a streaming RPC with a signal handler that will raise.""" channel = grpc.insecure_channel(server_target) try: - for _ in channel.unary_stream(UNARY_STREAM)( - _MESSAGE, wait_for_ready=True - ): + for _ in channel.unary_stream( + UNARY_STREAM, + _registered_method=True, + )(_MESSAGE, wait_for_ready=True): pass except KeyboardInterrupt: sys.stderr.write("Running signal handler.\n") diff --git a/src/python/grpcio_tests/tests/unit/_xds_credentials_test.py b/src/python/grpcio_tests/tests/unit/_xds_credentials_test.py index 977d564888d..6d8b2b6a041 100644 --- a/src/python/grpcio_tests/tests/unit/_xds_credentials_test.py +++ b/src/python/grpcio_tests/tests/unit/_xds_credentials_test.py @@ -71,9 +71,10 @@ class XdsCredentialsTest(unittest.TestCase): server_address, channel_creds, options=override_options ) as channel: request = b"abc" - response = channel.unary_unary("/test/method")( - request, wait_for_ready=True - ) + response = channel.unary_unary( + "/test/method", + _registered_method=True, + )(request, wait_for_ready=True) self.assertEqual(response, request) def test_xds_creds_fallback_insecure(self): @@ -89,9 +90,10 @@ class XdsCredentialsTest(unittest.TestCase): channel_creds = grpc.xds_channel_credentials(channel_fallback_creds) with grpc.secure_channel(server_address, channel_creds) as channel: request = b"abc" - response = channel.unary_unary("/test/method")( - request, wait_for_ready=True - ) + response = channel.unary_unary( + "/test/method", + _registered_method=True, + )(request, wait_for_ready=True) self.assertEqual(response, request) def test_start_xds_server(self): diff --git a/src/python/grpcio_tests/tests_gevent/unit/close_channel_test.py b/src/python/grpcio_tests/tests_gevent/unit/close_channel_test.py index 47fdb2c22e7..f09c47734e0 100644 --- a/src/python/grpcio_tests/tests_gevent/unit/close_channel_test.py +++ b/src/python/grpcio_tests/tests_gevent/unit/close_channel_test.py @@ -65,6 +65,7 @@ class CloseChannelTest(unittest.TestCase): _UNARY_CALL_METHOD_WITH_SLEEP, request_serializer=messages_pb2.SimpleRequest.SerializeToString, response_deserializer=messages_pb2.SimpleResponse.FromString, + _registered_method=True, ) greenlet = group.spawn(self._run_client, UnaryCallWithSleep) # release loop so that greenlet can take control @@ -78,6 +79,7 @@ class CloseChannelTest(unittest.TestCase): _UNARY_CALL_METHOD_WITH_SLEEP, request_serializer=messages_pb2.SimpleRequest.SerializeToString, response_deserializer=messages_pb2.SimpleResponse.FromString, + _registered_method=True, ) greenlet = group.spawn(self._run_client, UnaryCallWithSleep) # release loop so that greenlet can take control diff --git a/src/python/grpcio_tests/tests_py3_only/unit/_leak_test.py b/src/python/grpcio_tests/tests_py3_only/unit/_leak_test.py index c917bd10521..06fa6466014 100644 --- a/src/python/grpcio_tests/tests_py3_only/unit/_leak_test.py +++ b/src/python/grpcio_tests/tests_py3_only/unit/_leak_test.py @@ -68,7 +68,10 @@ def _start_a_test_server(): def _perform_an_rpc(address): channel = grpc.insecure_channel(address) - multicallable = channel.unary_unary(_TEST_METHOD) + multicallable = channel.unary_unary( + _TEST_METHOD, + _registered_method=True, + ) response = multicallable(_REQUEST) assert _REQUEST == response diff --git a/src/python/grpcio_tests/tests_py3_only/unit/_simple_stubs_test.py b/src/python/grpcio_tests/tests_py3_only/unit/_simple_stubs_test.py index 771097936f6..adcc1299e9c 100644 --- a/src/python/grpcio_tests/tests_py3_only/unit/_simple_stubs_test.py +++ b/src/python/grpcio_tests/tests_py3_only/unit/_simple_stubs_test.py @@ -193,6 +193,7 @@ class SimpleStubsTest(unittest.TestCase): _UNARY_UNARY, channel_credentials=grpc.experimental.insecure_channel_credentials(), timeout=None, + _registered_method=0, ) self.assertEqual(_REQUEST, response) @@ -205,6 +206,7 @@ class SimpleStubsTest(unittest.TestCase): _UNARY_UNARY, channel_credentials=grpc.local_channel_credentials(), timeout=None, + _registered_method=0, ) self.assertEqual(_REQUEST, response) @@ -213,7 +215,10 @@ class SimpleStubsTest(unittest.TestCase): target = f"localhost:{port}" test_name = inspect.stack()[0][3] args = (_REQUEST, target, _UNARY_UNARY) - kwargs = {"channel_credentials": grpc.local_channel_credentials()} + kwargs = { + "channel_credentials": grpc.local_channel_credentials(), + "_registered_method": True, + } def _invoke(seed: str): run_kwargs = dict(kwargs) @@ -230,6 +235,7 @@ class SimpleStubsTest(unittest.TestCase): target, _UNARY_UNARY, channel_credentials=grpc.local_channel_credentials(), + _registered_method=0, ) self.assert_eventually( lambda: grpc._simple_stubs.ChannelCache.get()._test_only_channel_count() @@ -250,6 +256,7 @@ class SimpleStubsTest(unittest.TestCase): _UNARY_UNARY, options=options, channel_credentials=grpc.local_channel_credentials(), + _registered_method=0, ) self.assert_eventually( lambda: grpc._simple_stubs.ChannelCache.get()._test_only_channel_count() @@ -265,6 +272,7 @@ class SimpleStubsTest(unittest.TestCase): target, _UNARY_STREAM, channel_credentials=grpc.local_channel_credentials(), + _registered_method=0, ): self.assertEqual(_REQUEST, response) @@ -280,6 +288,7 @@ class SimpleStubsTest(unittest.TestCase): target, _STREAM_UNARY, channel_credentials=grpc.local_channel_credentials(), + _registered_method=0, ) self.assertEqual(_REQUEST, response) @@ -295,6 +304,7 @@ class SimpleStubsTest(unittest.TestCase): target, _STREAM_STREAM, channel_credentials=grpc.local_channel_credentials(), + _registered_method=0, ): self.assertEqual(_REQUEST, response) @@ -319,14 +329,22 @@ class SimpleStubsTest(unittest.TestCase): with _server(server_creds) as port: target = f"localhost:{port}" response = grpc.experimental.unary_unary( - _REQUEST, target, _UNARY_UNARY, options=_property_options + _REQUEST, + target, + _UNARY_UNARY, + options=_property_options, + _registered_method=0, ) def test_insecure_sugar(self): with _server(None) as port: target = f"localhost:{port}" response = grpc.experimental.unary_unary( - _REQUEST, target, _UNARY_UNARY, insecure=True + _REQUEST, + target, + _UNARY_UNARY, + insecure=True, + _registered_method=0, ) self.assertEqual(_REQUEST, response) @@ -340,14 +358,24 @@ class SimpleStubsTest(unittest.TestCase): _UNARY_UNARY, insecure=True, channel_credentials=grpc.local_channel_credentials(), + _registered_method=0, ) def test_default_wait_for_ready(self): addr, port, sock = get_socket() sock.close() target = f"{addr}:{port}" - channel = grpc._simple_stubs.ChannelCache.get().get_channel( - target, (), None, True, None + ( + channel, + unused_method_handle, + ) = grpc._simple_stubs.ChannelCache.get().get_channel( + target=target, + options=(), + channel_credentials=None, + insecure=True, + compression=None, + method=_UNARY_UNARY, + _registered_method=True, ) rpc_finished_event = threading.Event() rpc_failed_event = threading.Event() @@ -376,7 +404,12 @@ class SimpleStubsTest(unittest.TestCase): def _send_rpc(): try: response = grpc.experimental.unary_unary( - _REQUEST, target, _UNARY_UNARY, timeout=None, insecure=True + _REQUEST, + target, + _UNARY_UNARY, + timeout=None, + insecure=True, + _registered_method=0, ) rpc_finished_event.set() except Exception as e: @@ -399,6 +432,7 @@ class SimpleStubsTest(unittest.TestCase): target, _BLACK_HOLE, insecure=True, + _registered_method=0, **invocation_args, ) self.assertEqual( From 0df505d9dbcede9726b7992f92d13585c96dff83 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 8 Jan 2024 16:51:36 -0800 Subject: [PATCH 12/27] [api_fuzzer] Cap the number of comma-delimited strings in the target URI to 1K. PiperOrigin-RevId: 596739224 --- test/core/end2end/fuzzers/api_fuzzer.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index d58e143b996..3cec7990f42 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -29,6 +29,8 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" @@ -407,6 +409,21 @@ void ApiFuzzer::Tick() { } } +namespace { + +// If there are more than 1K comma-delimited strings in target, remove +// the extra ones. +std::string SanitizeTargetUri(absl::string_view target) { + constexpr size_t kMaxCommaDelimitedStrings = 1000; + std::vector parts = absl::StrSplit(target, ','); + if (parts.size() > kMaxCommaDelimitedStrings) { + parts.resize(kMaxCommaDelimitedStrings); + } + return absl::StrJoin(parts, ","); +} + +} // namespace + ApiFuzzer::Result ApiFuzzer::CreateChannel( const api_fuzzer::CreateChannel& create_channel) { if (channel_ != nullptr) return Result::kComplete; @@ -423,8 +440,9 @@ ApiFuzzer::Result ApiFuzzer::CreateChannel( create_channel.has_channel_creds() ? ReadChannelCreds(create_channel.channel_creds()) : grpc_insecure_credentials_create(); - channel_ = grpc_channel_create(create_channel.target().c_str(), creds, - args.ToC().get()); + channel_ = + grpc_channel_create(SanitizeTargetUri(create_channel.target()).c_str(), + creds, args.ToC().get()); grpc_channel_credentials_release(creds); } GPR_ASSERT(channel_ != nullptr); From f5acbf79e2492d25c034f4dcbd85ac13aa3b519a Mon Sep 17 00:00:00 2001 From: Vignesh Babu Date: Tue, 9 Jan 2024 17:30:44 +0000 Subject: [PATCH 13/27] [flakiness] Fix timeout flakiness in //test/core/end2end:cancel_after_invoke_test Based on discussions with drfloob@ PiperOrigin-RevId: 596958525 --- .../ext/transport/chttp2/server/chttp2_server.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index e5a6282024e..dea28445a4f 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -617,8 +617,17 @@ void Chttp2ServerListener::ActiveConnection::Start( RefCountedPtr handshaking_state_ref; listener_ = std::move(listener); { - MutexLock lock(&mu_); - if (shutdown_) return; + ReleasableMutexLock lock(&mu_); + if (shutdown_) { + lock.Release(); + // If the Connection is already shutdown at this point, it implies the + // owning Chttp2ServerListener and all associated ActiveConnections have + // been orphaned. The generated endpoints need to be shutdown here to + // ensure the tcp connections are closed appropriately. + grpc_endpoint_shutdown(endpoint, absl::OkStatus()); + grpc_endpoint_destroy(endpoint); + return; + } // Hold a ref to HandshakingState to allow starting the handshake outside // the critical region. handshaking_state_ref = handshaking_state_->Ref(); From 5aa832f7b930c58c6e4447500cb8ed5d3eb26efe Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 9 Jan 2024 17:58:39 +0000 Subject: [PATCH 14/27] [Cleanup] Fix abseil include error (#35478) Fixed ``` /var/local/git/grpc/src/core/ext/transport/chaotic_good/frame_header.cc:69:15: error: no member named 'StrCat' in namespace 'absl' absl::StrCat("Invalid header length: ", header.header_length)); ~~~~~~^ ``` Closes #35478 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35478 from veblush:fix-header d6c94b63e7aa0711a63f1d43526c5cc18d62fdb4 PiperOrigin-RevId: 596966091 --- src/core/BUILD | 1 + src/core/ext/transport/chaotic_good/frame_header.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/BUILD b/src/core/BUILD index 8ee2f308b86..776a390ff0d 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -6237,6 +6237,7 @@ grpc_cc_library( external_deps = [ "absl/status", "absl/status:statusor", + "absl/strings", ], deps = [ "bitset", diff --git a/src/core/ext/transport/chaotic_good/frame_header.cc b/src/core/ext/transport/chaotic_good/frame_header.cc index 06f9d146e66..6b1ec018491 100644 --- a/src/core/ext/transport/chaotic_good/frame_header.cc +++ b/src/core/ext/transport/chaotic_good/frame_header.cc @@ -19,6 +19,7 @@ #include #include "absl/status/status.h" +#include "absl/strings/str_cat.h" #include From 5888738c5a2f66d758dd1a8735764b4b279a376f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 9 Jan 2024 17:59:05 +0000 Subject: [PATCH 15/27] [OTel] Add a PluginOption API (#35434) Closes #35434 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35434 from yashykt:OTelPluginOption 1db870bed4ba55cad5515c3586200fa17f5ce226 PiperOrigin-RevId: 596966190 --- include/grpcpp/ext/csm_observability.h | 14 + include/grpcpp/ext/otel_plugin.h | 12 + src/core/lib/channel/call_tracer.h | 3 +- src/core/lib/surface/call.cc | 4 +- src/cpp/ext/csm/csm_observability.cc | 81 +++-- src/cpp/ext/csm/metadata_exchange.cc | 4 +- src/cpp/ext/csm/metadata_exchange.h | 4 +- .../ext/filters/census/server_call_tracer.cc | 2 +- .../ext/filters/census/server_call_tracer.h | 2 +- src/cpp/ext/otel/key_value_iterable.h | 33 ++- src/cpp/ext/otel/otel_call_tracer.h | 2 + src/cpp/ext/otel/otel_client_filter.cc | 50 +++- src/cpp/ext/otel/otel_client_filter.h | 13 +- src/cpp/ext/otel/otel_plugin.cc | 22 ++ src/cpp/ext/otel/otel_plugin.h | 73 ++++- src/cpp/ext/otel/otel_server_call_tracer.cc | 41 ++- src/cpp/ext/otel/otel_server_call_tracer.h | 3 +- .../grpc_observability/server_call_tracer.cc | 3 +- .../grpc_observability/server_call_tracer.h | 3 +- .../server_call_tracer_factory_test.cc | 3 +- test/core/end2end/tests/http2_stats.cc | 3 +- test/cpp/ext/csm/BUILD | 2 + test/cpp/ext/csm/csm_observability_test.cc | 7 + test/cpp/ext/otel/otel_plugin_test.cc | 276 ++++++++++++++++++ test/cpp/ext/otel/otel_test_library.cc | 8 +- test/cpp/ext/otel/otel_test_library.h | 5 +- test/cpp/interop/observability_client.cc | 4 +- 27 files changed, 607 insertions(+), 70 deletions(-) diff --git a/include/grpcpp/ext/csm_observability.h b/include/grpcpp/ext/csm_observability.h index 1212ddf62a6..58a9e96aefc 100644 --- a/include/grpcpp/ext/csm_observability.h +++ b/include/grpcpp/ext/csm_observability.h @@ -28,6 +28,8 @@ #include "absl/strings/string_view.h" #include "opentelemetry/sdk/metrics/meter_provider.h" +#include + namespace grpc { namespace internal { @@ -88,6 +90,18 @@ class CsmObservabilityBuilder { std::unique_ptr builder_; }; +class OpenTelemetryPluginOption; + +/// Creates an OpenTelemetryPluginOption that would add additional labels on +/// gRPC metrics to enhance observability for CSM users. +/// +/// Sample Usage - +/// OpenTelemetryPluginBuilder() +/// .SetMeterProvider(provider) +/// .AddPluginOption(MakeCsmOpenTelemetryPluginOption()) +/// .BuildAndRegisterGlobal(); +std::unique_ptr MakeCsmOpenTelemetryPluginOption(); + } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/ext/otel_plugin.h b/include/grpcpp/ext/otel_plugin.h index bdf681ec6da..acb3532c5fd 100644 --- a/include/grpcpp/ext/otel_plugin.h +++ b/include/grpcpp/ext/otel_plugin.h @@ -38,6 +38,11 @@ class OpenTelemetryPluginBuilderImpl; namespace experimental { +class OpenTelemetryPluginOption { + public: + virtual ~OpenTelemetryPluginOption() = default; +}; + /// The most common way to use this API is - /// /// OpenTelemetryPluginBuilder().SetMeterProvider(provider).BuildAndRegister(); @@ -76,6 +81,7 @@ class OpenTelemetryPluginBuilder { "grpc.server.call.rcvd_total_compressed_message_size"; OpenTelemetryPluginBuilder(); + ~OpenTelemetryPluginBuilder(); /// If `SetMeterProvider()` is not called, no metrics are collected. OpenTelemetryPluginBuilder& SetMeterProvider( std::shared_ptr meter_provider); @@ -95,6 +101,12 @@ class OpenTelemetryPluginBuilder { OpenTelemetryPluginBuilder& SetGenericMethodAttributeFilter( absl::AnyInvocable generic_method_attribute_filter); + /// Add a plugin option to add to the opentelemetry plugin being built. At + /// present, this type is an opaque type. Ownership of \a option is + /// transferred when `AddPluginOption` is invoked. A maximum of 64 plugin + /// options can be added. + OpenTelemetryPluginBuilder& AddPluginOption( + std::unique_ptr option); /// Registers a global plugin that acts on all channels and servers running on /// the process. void BuildAndRegisterGlobal(); diff --git a/src/core/lib/channel/call_tracer.h b/src/core/lib/channel/call_tracer.h index 78fd7fbb369..3f2b10ead22 100644 --- a/src/core/lib/channel/call_tracer.h +++ b/src/core/lib/channel/call_tracer.h @@ -175,7 +175,8 @@ class ServerCallTracerFactory { virtual ~ServerCallTracerFactory() {} - virtual ServerCallTracer* CreateNewServerCallTracer(Arena* arena) = 0; + virtual ServerCallTracer* CreateNewServerCallTracer( + Arena* arena, const ChannelArgs& channel_args) = 0; // Returns true if a server is to be traced, false otherwise. virtual bool IsServerTraced(const ChannelArgs& /*args*/) { return true; } diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 2702bedc0e7..d6d6a8537c6 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -859,7 +859,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args, args->server->server_call_tracer_factory() != nullptr) { auto* server_call_tracer = args->server->server_call_tracer_factory()->CreateNewServerCallTracer( - arena); + arena, args->server->channel_args()); if (server_call_tracer != nullptr) { // Note that we are setting both // GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE and @@ -3426,7 +3426,7 @@ ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena, if (args->server->server_call_tracer_factory() != nullptr) { auto* server_call_tracer = args->server->server_call_tracer_factory()->CreateNewServerCallTracer( - arena); + arena, args->server->channel_args()); if (server_call_tracer != nullptr) { // Note that we are setting both // GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE and diff --git a/src/cpp/ext/csm/csm_observability.cc b/src/cpp/ext/csm/csm_observability.cc index 625120ac2e2..de55e1e9d73 100644 --- a/src/cpp/ext/csm/csm_observability.cc +++ b/src/cpp/ext/csm/csm_observability.cc @@ -42,6 +42,58 @@ #include "src/cpp/ext/otel/otel_plugin.h" namespace grpc { + +namespace internal { + +bool CsmServerSelector(const grpc_core::ChannelArgs& args) { + return args.GetBool(GRPC_ARG_XDS_ENABLED_SERVER).value_or(false); +} + +bool CsmChannelTargetSelector(absl::string_view target) { + auto uri = grpc_core::URI::Parse(target); + if (!uri.ok()) { + gpr_log(GPR_ERROR, "Failed to parse URI: %s", std::string(target).c_str()); + return false; + } + // CSM channels should have an "xds" scheme + if (uri->scheme() != "xds") { + return false; + } + // If set, the authority should be TD + if (!uri->authority().empty() && + uri->authority() != "traffic-director-global.xds.googleapis.com") { + return false; + } + return true; +} + +class CsmOpenTelemetryPluginOption + : public grpc::internal::InternalOpenTelemetryPluginOption { + public: + CsmOpenTelemetryPluginOption() + : labels_injector_(std::make_unique( + google::cloud::otel::MakeResourceDetector() + ->Detect() + .GetAttributes())) {} + + bool IsActiveOnClientChannel(absl::string_view target) const override { + return CsmChannelTargetSelector(target); + } + + bool IsActiveOnServer(const grpc_core::ChannelArgs& args) const override { + return CsmServerSelector(args); + } + + const grpc::internal::LabelsInjector* labels_injector() const override { + return labels_injector_.get(); + } + + private: + std::unique_ptr labels_injector_; +}; + +} // namespace internal + namespace experimental { // @@ -78,9 +130,7 @@ CsmObservabilityBuilder::SetGenericMethodAttributeFilter( } absl::StatusOr CsmObservabilityBuilder::BuildAndRegister() { - builder_->SetServerSelector([](const grpc_core::ChannelArgs& args) { - return args.GetBool(GRPC_ARG_XDS_ENABLED_SERVER).value_or(false); - }); + builder_->SetServerSelector(internal::CsmServerSelector); builder_->SetTargetSelector(internal::CsmChannelTargetSelector); builder_->SetLabelsInjector( std::make_unique( @@ -91,27 +141,10 @@ absl::StatusOr CsmObservabilityBuilder::BuildAndRegister() { return CsmObservability(); } -} // namespace experimental - -namespace internal { - -bool CsmChannelTargetSelector(absl::string_view target) { - auto uri = grpc_core::URI::Parse(target); - if (!uri.ok()) { - gpr_log(GPR_ERROR, "Failed to parse URI: %s", std::string(target).c_str()); - return false; - } - // CSM channels should have an "xds" scheme - if (uri->scheme() != "xds") { - return false; - } - // If set, the authority should be TD - if (!uri->authority().empty() && - uri->authority() != "traffic-director-global.xds.googleapis.com") { - return false; - } - return true; +std::unique_ptr MakeCsmOpenTelemetryPluginOption() { + return std::make_unique(); } -} // namespace internal +} // namespace experimental + } // namespace grpc diff --git a/src/cpp/ext/csm/metadata_exchange.cc b/src/cpp/ext/csm/metadata_exchange.cc index c1beaddb483..e0a34827658 100644 --- a/src/cpp/ext/csm/metadata_exchange.cc +++ b/src/cpp/ext/csm/metadata_exchange.cc @@ -404,7 +404,7 @@ ServiceMeshLabelsInjector::ServiceMeshLabelsInjector( } std::unique_ptr ServiceMeshLabelsInjector::GetLabels( - grpc_metadata_batch* incoming_initial_metadata) { + grpc_metadata_batch* incoming_initial_metadata) const { auto peer_metadata = incoming_initial_metadata->Take(grpc_core::XEnvoyPeerMetadata()); return std::make_unique( @@ -414,7 +414,7 @@ std::unique_ptr ServiceMeshLabelsInjector::GetLabels( void ServiceMeshLabelsInjector::AddLabels( grpc_metadata_batch* outgoing_initial_metadata, - LabelsIterable* labels_from_incoming_metadata) { + LabelsIterable* labels_from_incoming_metadata) const { // On the server, if the labels from incoming metadata did not have a // non-empty base64 encoded "x-envoy-peer-metadata", do not perform metadata // exchange. diff --git a/src/cpp/ext/csm/metadata_exchange.h b/src/cpp/ext/csm/metadata_exchange.h index 9205b39306f..c2c24ff2843 100644 --- a/src/cpp/ext/csm/metadata_exchange.h +++ b/src/cpp/ext/csm/metadata_exchange.h @@ -43,12 +43,12 @@ class ServiceMeshLabelsInjector : public LabelsInjector { // Read the incoming initial metadata to get the set of labels to be added to // metrics. std::unique_ptr GetLabels( - grpc_metadata_batch* incoming_initial_metadata) override; + grpc_metadata_batch* incoming_initial_metadata) const override; // Modify the outgoing initial metadata with metadata information to be sent // to the peer. void AddLabels(grpc_metadata_batch* outgoing_initial_metadata, - LabelsIterable* labels_from_incoming_metadata) override; + LabelsIterable* labels_from_incoming_metadata) const override; private: std::vector> local_labels_; diff --git a/src/cpp/ext/filters/census/server_call_tracer.cc b/src/cpp/ext/filters/census/server_call_tracer.cc index 20971ab18d2..33534b9a28e 100644 --- a/src/cpp/ext/filters/census/server_call_tracer.cc +++ b/src/cpp/ext/filters/census/server_call_tracer.cc @@ -265,7 +265,7 @@ void OpenCensusServerCallTracer::RecordEnd( grpc_core::ServerCallTracer* OpenCensusServerCallTracerFactory::CreateNewServerCallTracer( - grpc_core::Arena* arena) { + grpc_core::Arena* arena, const grpc_core::ChannelArgs& /*args*/) { return arena->ManagedNew(); } diff --git a/src/cpp/ext/filters/census/server_call_tracer.h b/src/cpp/ext/filters/census/server_call_tracer.h index 7eb95c62c1a..4a11b4e8c53 100644 --- a/src/cpp/ext/filters/census/server_call_tracer.h +++ b/src/cpp/ext/filters/census/server_call_tracer.h @@ -31,7 +31,7 @@ class OpenCensusServerCallTracerFactory : public grpc_core::ServerCallTracerFactory { public: grpc_core::ServerCallTracer* CreateNewServerCallTracer( - grpc_core::Arena* arena) override; + grpc_core::Arena* arena, const grpc_core::ChannelArgs& /*args*/) override; }; } // namespace internal diff --git a/src/cpp/ext/otel/key_value_iterable.h b/src/cpp/ext/otel/key_value_iterable.h index 9395326c53f..89d0e6a2630 100644 --- a/src/cpp/ext/otel/key_value_iterable.h +++ b/src/cpp/ext/otel/key_value_iterable.h @@ -50,9 +50,13 @@ class KeyValueIterable : public opentelemetry::common::KeyValueIterable { public: explicit KeyValueIterable( LabelsIterable* injected_labels_iterable, + const std::vector>& + injected_labels_from_plugin_options, absl::Span> additional_labels) : injected_labels_iterable_(injected_labels_iterable), + injected_labels_from_plugin_options_( + injected_labels_from_plugin_options), additional_labels_(additional_labels) {} bool ForEachKeyValue(opentelemetry::nostd::function_ref< @@ -68,6 +72,18 @@ class KeyValueIterable : public opentelemetry::common::KeyValueIterable { } } } + for (const auto& plugin_option_injected_iterable : + injected_labels_from_plugin_options_) { + if (plugin_option_injected_iterable != nullptr) { + plugin_option_injected_iterable->ResetIteratorPosition(); + while (const auto& pair = plugin_option_injected_iterable->Next()) { + if (!callback(AbslStrViewToOpenTelemetryStrView(pair->first), + AbslStrViewToOpenTelemetryStrView(pair->second))) { + return false; + } + } + } + } for (const auto& pair : additional_labels_) { if (!callback(AbslStrViewToOpenTelemetryStrView(pair.first), AbslStrViewToOpenTelemetryStrView(pair.second))) { @@ -78,14 +94,23 @@ class KeyValueIterable : public opentelemetry::common::KeyValueIterable { } size_t size() const noexcept override { - return (injected_labels_iterable_ != nullptr - ? injected_labels_iterable_->Size() - : 0) + - additional_labels_.size(); + size_t size = injected_labels_iterable_ != nullptr + ? injected_labels_iterable_->Size() + : 0; + for (const auto& plugin_option_injected_iterable : + injected_labels_from_plugin_options_) { + if (plugin_option_injected_iterable != nullptr) { + size += plugin_option_injected_iterable->Size(); + } + } + size += additional_labels_.size(); + return size; } private: LabelsIterable* injected_labels_iterable_; + const std::vector>& + injected_labels_from_plugin_options_; absl::Span> additional_labels_; }; diff --git a/src/cpp/ext/otel/otel_call_tracer.h b/src/cpp/ext/otel/otel_call_tracer.h index 7544bc602a4..8b90c92835f 100644 --- a/src/cpp/ext/otel/otel_call_tracer.h +++ b/src/cpp/ext/otel/otel_call_tracer.h @@ -98,6 +98,8 @@ class OpenTelemetryCallTracer : public grpc_core::ClientCallTracer { // Start time (for measuring latency). absl::Time start_time_; std::unique_ptr injected_labels_; + std::vector> + injected_labels_from_plugin_options_; }; explicit OpenTelemetryCallTracer(OpenTelemetryClientFilter* parent, diff --git a/src/cpp/ext/otel/otel_client_filter.cc b/src/cpp/ext/otel/otel_client_filter.cc index 640699d589b..4587b3836d5 100644 --- a/src/cpp/ext/otel/otel_client_filter.cc +++ b/src/cpp/ext/otel/otel_client_filter.cc @@ -73,14 +73,8 @@ const grpc_channel_filter OpenTelemetryClientFilter::kFilter = absl::StatusOr OpenTelemetryClientFilter::Create( const grpc_core::ChannelArgs& args, ChannelFilter::Args /*filter_args*/) { - std::string target = args.GetOwnedString(GRPC_ARG_SERVER_URI).value_or(""); - // Use the original target string only if a filter on the attribute is not - // registered or if the filter returns true, otherwise use "other". - if (OpenTelemetryPluginState().target_attribute_filter == nullptr || - OpenTelemetryPluginState().target_attribute_filter(target)) { - return OpenTelemetryClientFilter(std::move(target)); - } - return OpenTelemetryClientFilter("other"); + return OpenTelemetryClientFilter( + args.GetOwnedString(GRPC_ARG_SERVER_URI).value_or("")); } grpc_core::ArenaPromise @@ -106,6 +100,19 @@ OpenTelemetryClientFilter::MakeCallPromise( return next_promise_factory(std::move(call_args)); } +OpenTelemetryClientFilter::OpenTelemetryClientFilter(std::string target) + : active_plugin_options_view_( + ActivePluginOptionsView::MakeForClient(target)) { + // Use the original target string only if a filter on the attribute is not + // registered or if the filter returns true, otherwise use "other". + if (OpenTelemetryPluginState().target_attribute_filter == nullptr || + OpenTelemetryPluginState().target_attribute_filter(target)) { + filtered_target_ = std::move(target); + } else { + filtered_target_ = "other"; + } +} + // // OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer // @@ -120,11 +127,11 @@ OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer:: std::array, 2> additional_labels = { {{OpenTelemetryMethodKey(), parent_->MethodForStats()}, - {OpenTelemetryTargetKey(), parent_->parent_->target()}}}; + {OpenTelemetryTargetKey(), parent_->parent_->filtered_target()}}}; // We might not have all the injected labels that we want at this point, so // avoid recording a subset of injected labels here. OpenTelemetryPluginState().client.attempt.started->Add( - 1, KeyValueIterable(/*injected_labels_iterable=*/nullptr, + 1, KeyValueIterable(/*injected_labels_iterable=*/nullptr, {}, additional_labels)); } } @@ -135,6 +142,15 @@ void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer:: injected_labels_ = OpenTelemetryPluginState().labels_injector->GetLabels( recv_initial_metadata); } + parent_->parent_->active_plugin_options_view().ForEach( + [&](const InternalOpenTelemetryPluginOption& plugin_option, + size_t /*index*/) { + auto* labels_injector = plugin_option.labels_injector(); + if (labels_injector != nullptr) { + injected_labels_from_plugin_options_.push_back( + labels_injector->GetLabels(recv_initial_metadata)); + } + }); } void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer:: @@ -143,6 +159,14 @@ void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer:: OpenTelemetryPluginState().labels_injector->AddLabels(send_initial_metadata, nullptr); } + parent_->parent_->active_plugin_options_view().ForEach( + [&](const InternalOpenTelemetryPluginOption& plugin_option, + size_t /*index*/) { + auto* labels_injector = plugin_option.labels_injector(); + if (labels_injector != nullptr) { + labels_injector->AddLabels(send_initial_metadata, nullptr); + } + }); } void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::RecordSendMessage( @@ -178,11 +202,13 @@ void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer:: std::array, 3> additional_labels = { {{OpenTelemetryMethodKey(), parent_->MethodForStats()}, - {OpenTelemetryTargetKey(), parent_->parent_->target()}, + {OpenTelemetryTargetKey(), parent_->parent_->filtered_target()}, {OpenTelemetryStatusKey(), grpc_status_code_to_string( static_cast(status.code()))}}}; - KeyValueIterable labels(injected_labels_.get(), additional_labels); + KeyValueIterable labels(injected_labels_.get(), + injected_labels_from_plugin_options_, + additional_labels); if (OpenTelemetryPluginState().client.attempt.duration != nullptr) { OpenTelemetryPluginState().client.attempt.duration->Record( absl::ToDoubleSeconds(absl::Now() - start_time_), labels, diff --git a/src/cpp/ext/otel/otel_client_filter.h b/src/cpp/ext/otel/otel_client_filter.h index 9205da43511..7c0ddcc6f98 100644 --- a/src/cpp/ext/otel/otel_client_filter.h +++ b/src/cpp/ext/otel/otel_client_filter.h @@ -32,6 +32,7 @@ #include "src/core/lib/channel/promise_based_filter.h" #include "src/core/lib/promise/arena_promise.h" #include "src/core/lib/transport/transport.h" +#include "src/cpp/ext/otel/otel_plugin.h" namespace grpc { namespace internal { @@ -48,13 +49,17 @@ class OpenTelemetryClientFilter : public grpc_core::ChannelFilter { grpc_core::CallArgs call_args, grpc_core::NextPromiseFactory next_promise_factory) override; - absl::string_view target() const { return target_; } + absl::string_view filtered_target() const { return filtered_target_; } + + const ActivePluginOptionsView& active_plugin_options_view() const { + return active_plugin_options_view_; + } private: - explicit OpenTelemetryClientFilter(std::string target) - : target_(std::move(target)) {} + explicit OpenTelemetryClientFilter(std::string target); - std::string target_; + std::string filtered_target_; + ActivePluginOptionsView active_plugin_options_view_; }; } // namespace internal diff --git a/src/cpp/ext/otel/otel_plugin.cc b/src/cpp/ext/otel/otel_plugin.cc index 3a7c8bd0dd5..51b50615b31 100644 --- a/src/cpp/ext/otel/otel_plugin.cc +++ b/src/cpp/ext/otel/otel_plugin.cc @@ -89,6 +89,8 @@ absl::flat_hash_set BaseMetrics() { OpenTelemetryPluginBuilderImpl::OpenTelemetryPluginBuilderImpl() : metrics_(BaseMetrics()) {} +OpenTelemetryPluginBuilderImpl::~OpenTelemetryPluginBuilderImpl() = default; + OpenTelemetryPluginBuilderImpl& OpenTelemetryPluginBuilderImpl::SetMeterProvider( std::shared_ptr meter_provider) { @@ -153,6 +155,14 @@ OpenTelemetryPluginBuilderImpl::SetServerSelector( return *this; } +OpenTelemetryPluginBuilderImpl& OpenTelemetryPluginBuilderImpl::AddPluginOption( + std::unique_ptr option) { + // We allow a limit of 64 plugin options to be registered at this time. + GPR_ASSERT(plugin_options_.size() < 64); + plugin_options_.push_back(std::move(option)); + return *this; +} + void OpenTelemetryPluginBuilderImpl::BuildAndRegisterGlobal() { opentelemetry::nostd::shared_ptr meter_provider = meter_provider_; @@ -239,6 +249,7 @@ void OpenTelemetryPluginBuilderImpl::BuildAndRegisterGlobal() { g_otel_plugin_state_->generic_method_attribute_filter = std::move(generic_method_attribute_filter_); g_otel_plugin_state_->meter_provider = std::move(meter_provider); + g_otel_plugin_state_->plugin_options = std::move(plugin_options_); grpc_core::ServerCallTracerFactory::RegisterGlobal( new grpc::internal::OpenTelemetryServerCallTracerFactory()); grpc_core::CoreConfiguration::RegisterBuilder( @@ -287,6 +298,8 @@ constexpr absl::string_view OpenTelemetryPluginBuilder:: OpenTelemetryPluginBuilder::OpenTelemetryPluginBuilder() : impl_(std::make_unique()) {} +OpenTelemetryPluginBuilder::~OpenTelemetryPluginBuilder() = default; + OpenTelemetryPluginBuilder& OpenTelemetryPluginBuilder::SetMeterProvider( std::shared_ptr meter_provider) { impl_->SetMeterProvider(std::move(meter_provider)); @@ -310,6 +323,15 @@ OpenTelemetryPluginBuilder::SetGenericMethodAttributeFilter( return *this; } +OpenTelemetryPluginBuilder& OpenTelemetryPluginBuilder::AddPluginOption( + std::unique_ptr option) { + impl_->AddPluginOption( + std::unique_ptr( + static_cast( + option.release()))); + return *this; +} + void OpenTelemetryPluginBuilder::BuildAndRegisterGlobal() { impl_->BuildAndRegisterGlobal(); } diff --git a/src/cpp/ext/otel/otel_plugin.h b/src/cpp/ext/otel/otel_plugin.h index 3476850a57b..0aa31779c13 100644 --- a/src/cpp/ext/otel/otel_plugin.h +++ b/src/cpp/ext/otel/otel_plugin.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #include "opentelemetry/metrics/sync_instruments.h" #include "opentelemetry/nostd/shared_ptr.h" +#include + #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/transport/metadata_batch.h" @@ -67,14 +70,27 @@ class LabelsInjector { // Read the incoming initial metadata to get the set of labels to be added to // metrics. virtual std::unique_ptr GetLabels( - grpc_metadata_batch* incoming_initial_metadata) = 0; + grpc_metadata_batch* incoming_initial_metadata) const = 0; // Modify the outgoing initial metadata with metadata information to be sent // to the peer. On the server side, \a labels_from_incoming_metadata returned // from `GetLabels` should be provided as input here. On the client side, this // should be nullptr. - virtual void AddLabels(grpc_metadata_batch* outgoing_initial_metadata, - LabelsIterable* labels_from_incoming_metadata) = 0; + virtual void AddLabels( + grpc_metadata_batch* outgoing_initial_metadata, + LabelsIterable* labels_from_incoming_metadata) const = 0; +}; + +class InternalOpenTelemetryPluginOption + : public grpc::experimental::OpenTelemetryPluginOption { + public: + ~InternalOpenTelemetryPluginOption() override = default; + // Determines whether a plugin option is active on a given channel target + virtual bool IsActiveOnClientChannel(absl::string_view target) const = 0; + // Determines whether a plugin option is active on a given server + virtual bool IsActiveOnServer(const grpc_core::ChannelArgs& args) const = 0; + // Returns the LabelsInjector used by this plugin option, nullptr if none. + virtual const grpc::internal::LabelsInjector* labels_injector() const = 0; }; struct OpenTelemetryPluginState { @@ -107,6 +123,8 @@ struct OpenTelemetryPluginState { generic_method_attribute_filter; absl::AnyInvocable server_selector; + std::vector> + plugin_options; }; const struct OpenTelemetryPluginState& OpenTelemetryPluginState(); @@ -119,6 +137,7 @@ absl::string_view OpenTelemetryTargetKey(); class OpenTelemetryPluginBuilderImpl { public: OpenTelemetryPluginBuilderImpl(); + ~OpenTelemetryPluginBuilderImpl(); // If `SetMeterProvider()` is not called, no metrics are collected. OpenTelemetryPluginBuilderImpl& SetMeterProvider( std::shared_ptr meter_provider); @@ -166,6 +185,8 @@ class OpenTelemetryPluginBuilderImpl { OpenTelemetryPluginBuilderImpl& SetGenericMethodAttributeFilter( absl::AnyInvocable generic_method_attribute_filter); + OpenTelemetryPluginBuilderImpl& AddPluginOption( + std::unique_ptr option); void BuildAndRegisterGlobal(); private: @@ -179,6 +200,52 @@ class OpenTelemetryPluginBuilderImpl { generic_method_attribute_filter_; absl::AnyInvocable server_selector_; + std::vector> + plugin_options_; +}; + +// Creates a convenience wrapper to help iterate over only those plugin options +// that are active over a given channel/server. +class ActivePluginOptionsView { + public: + static ActivePluginOptionsView MakeForClient(absl::string_view target) { + return ActivePluginOptionsView( + [target](const InternalOpenTelemetryPluginOption& plugin_option) { + return plugin_option.IsActiveOnClientChannel(target); + }); + } + + static ActivePluginOptionsView MakeForServer( + const grpc_core::ChannelArgs& args) { + return ActivePluginOptionsView( + [&args](const InternalOpenTelemetryPluginOption& plugin_option) { + return plugin_option.IsActiveOnServer(args); + }); + } + + void ForEach( + absl::FunctionRef + func) const { + for (size_t i = 0; i < OpenTelemetryPluginState().plugin_options.size(); + ++i) { + const auto& plugin_option = OpenTelemetryPluginState().plugin_options[i]; + if (active_mask_[i]) func(*plugin_option, i); + } + } + + private: + explicit ActivePluginOptionsView( + absl::FunctionRef func) { + for (size_t i = 0; i < OpenTelemetryPluginState().plugin_options.size(); + ++i) { + const auto& plugin_option = OpenTelemetryPluginState().plugin_options[i]; + if (plugin_option != nullptr && func(*plugin_option)) { + active_mask_.set(i); + } + } + } + + std::bitset<64> active_mask_; }; } // namespace internal diff --git a/src/cpp/ext/otel/otel_server_call_tracer.cc b/src/cpp/ext/otel/otel_server_call_tracer.cc index ab7f3a993c3..7fa40c6ccc9 100644 --- a/src/cpp/ext/otel/otel_server_call_tracer.cc +++ b/src/cpp/ext/otel/otel_server_call_tracer.cc @@ -56,7 +56,12 @@ namespace { class OpenTelemetryServerCallTracer : public grpc_core::ServerCallTracer { public: - OpenTelemetryServerCallTracer() : start_time_(absl::Now()) {} + explicit OpenTelemetryServerCallTracer(const grpc_core::ChannelArgs& args) + : start_time_(absl::Now()), + active_plugin_options_view_( + ActivePluginOptionsView::MakeForServer(args)), + injected_labels_from_plugin_options_( + OpenTelemetryPluginState().plugin_options.size()) {} std::string TraceId() override { // Not implemented @@ -81,6 +86,16 @@ class OpenTelemetryServerCallTracer : public grpc_core::ServerCallTracer { OpenTelemetryPluginState().labels_injector->AddLabels( send_initial_metadata, injected_labels_.get()); } + active_plugin_options_view_.ForEach( + [&](const InternalOpenTelemetryPluginOption& plugin_option, + size_t index) { + auto* labels_injector = plugin_option.labels_injector(); + if (labels_injector != nullptr) { + labels_injector->AddLabels( + send_initial_metadata, + injected_labels_from_plugin_options_[index].get()); + } + }); } void RecordSendTrailingMetadata( @@ -148,6 +163,11 @@ class OpenTelemetryServerCallTracer : public grpc_core::ServerCallTracer { grpc_core::Slice path_; std::unique_ptr injected_labels_; bool registered_method_; + ActivePluginOptionsView active_plugin_options_view_; + // TODO(yashykt): It's wasteful to do this per call. When we re-haul the stats + // infrastructure, this should move to be done per server. + std::vector> + injected_labels_from_plugin_options_; }; void OpenTelemetryServerCallTracer::RecordReceivedInitialMetadata( @@ -158,6 +178,15 @@ void OpenTelemetryServerCallTracer::RecordReceivedInitialMetadata( injected_labels_ = OpenTelemetryPluginState().labels_injector->GetLabels( recv_initial_metadata); } + active_plugin_options_view_.ForEach( + [&](const InternalOpenTelemetryPluginOption& plugin_option, + size_t index) { + auto* labels_injector = plugin_option.labels_injector(); + if (labels_injector != nullptr) { + injected_labels_from_plugin_options_[index] = + labels_injector->GetLabels(recv_initial_metadata); + } + }); registered_method_ = recv_initial_metadata->get(grpc_core::GrpcRegisteredMethod()) .value_or(nullptr) != nullptr; @@ -167,7 +196,7 @@ void OpenTelemetryServerCallTracer::RecordReceivedInitialMetadata( // We might not have all the injected labels that we want at this point, so // avoid recording a subset of injected labels here. OpenTelemetryPluginState().server.call.started->Add( - 1, KeyValueIterable(/*injected_labels_iterable=*/nullptr, + 1, KeyValueIterable(/*injected_labels_iterable=*/nullptr, {}, additional_labels)); } } @@ -186,7 +215,9 @@ void OpenTelemetryServerCallTracer::RecordEnd( {{OpenTelemetryMethodKey(), MethodForStats()}, {OpenTelemetryStatusKey(), grpc_status_code_to_string(final_info->final_status)}}}; - KeyValueIterable labels(injected_labels_.get(), additional_labels); + KeyValueIterable labels(injected_labels_.get(), + injected_labels_from_plugin_options_, + additional_labels); if (OpenTelemetryPluginState().server.call.duration != nullptr) { OpenTelemetryPluginState().server.call.duration->Record( absl::ToDoubleSeconds(elapsed_time_), labels, @@ -216,8 +247,8 @@ void OpenTelemetryServerCallTracer::RecordEnd( grpc_core::ServerCallTracer* OpenTelemetryServerCallTracerFactory::CreateNewServerCallTracer( - grpc_core::Arena* arena) { - return arena->ManagedNew(); + grpc_core::Arena* arena, const grpc_core::ChannelArgs& args) { + return arena->ManagedNew(args); } bool OpenTelemetryServerCallTracerFactory::IsServerTraced( diff --git a/src/cpp/ext/otel/otel_server_call_tracer.h b/src/cpp/ext/otel/otel_server_call_tracer.h index 2ce422e9d5a..c8cea43d4d0 100644 --- a/src/cpp/ext/otel/otel_server_call_tracer.h +++ b/src/cpp/ext/otel/otel_server_call_tracer.h @@ -32,7 +32,8 @@ class OpenTelemetryServerCallTracerFactory : public grpc_core::ServerCallTracerFactory { public: grpc_core::ServerCallTracer* CreateNewServerCallTracer( - grpc_core::Arena* arena) override; + grpc_core::Arena* arena, + const grpc_core::ChannelArgs& channel_args) override; bool IsServerTraced(const grpc_core::ChannelArgs& args) override; }; diff --git a/src/python/grpcio_observability/grpc_observability/server_call_tracer.cc b/src/python/grpcio_observability/grpc_observability/server_call_tracer.cc index 722211a5c9e..6c1e68bfc37 100644 --- a/src/python/grpcio_observability/grpc_observability/server_call_tracer.cc +++ b/src/python/grpcio_observability/grpc_observability/server_call_tracer.cc @@ -261,10 +261,11 @@ void PythonOpenCensusServerCallTracer::RecordEnd( grpc_core::ServerCallTracer* PythonOpenCensusServerCallTracerFactory::CreateNewServerCallTracer( - grpc_core::Arena* arena) { + grpc_core::Arena* arena, const grpc_core::ChannelArgs& channel_args) { // We don't use arena here to to ensure that memory is allocated and freed in // the same DLL in Windows. (void)arena; + (void)channel_args; return new PythonOpenCensusServerCallTracer(); } diff --git a/src/python/grpcio_observability/grpc_observability/server_call_tracer.h b/src/python/grpcio_observability/grpc_observability/server_call_tracer.h index a4354b69b8c..3792ae00f8b 100644 --- a/src/python/grpcio_observability/grpc_observability/server_call_tracer.h +++ b/src/python/grpcio_observability/grpc_observability/server_call_tracer.h @@ -30,7 +30,8 @@ class PythonOpenCensusServerCallTracerFactory : public grpc_core::ServerCallTracerFactory { public: grpc_core::ServerCallTracer* CreateNewServerCallTracer( - grpc_core::Arena* arena) override; + grpc_core::Arena* arena, + const grpc_core::ChannelArgs& channel_args) override; }; inline absl::string_view GetMethod(const grpc_core::Slice& path) { diff --git a/test/core/channel/server_call_tracer_factory_test.cc b/test/core/channel/server_call_tracer_factory_test.cc index 09e79852fea..77862155b6c 100644 --- a/test/core/channel/server_call_tracer_factory_test.cc +++ b/test/core/channel/server_call_tracer_factory_test.cc @@ -26,7 +26,8 @@ namespace { class TestServerCallTracerFactory : public ServerCallTracerFactory { public: - ServerCallTracer* CreateNewServerCallTracer(Arena* /*arena*/) override { + ServerCallTracer* CreateNewServerCallTracer( + Arena* /*arena*/, const ChannelArgs& /*args*/) override { Crash("Not implemented"); } }; diff --git a/test/core/end2end/tests/http2_stats.cc b/test/core/end2end/tests/http2_stats.cc index 5986039e421..14f8dbeb648 100644 --- a/test/core/end2end/tests/http2_stats.cc +++ b/test/core/end2end/tests/http2_stats.cc @@ -200,7 +200,8 @@ grpc_transport_stream_stats FakeServerCallTracer::transport_stream_stats_; class FakeServerCallTracerFactory : public ServerCallTracerFactory { public: - ServerCallTracer* CreateNewServerCallTracer(Arena* arena) override { + ServerCallTracer* CreateNewServerCallTracer( + Arena* arena, const ChannelArgs& /*args*/) override { return arena->ManagedNew(); } }; diff --git a/test/cpp/ext/csm/BUILD b/test/cpp/ext/csm/BUILD index ed511175d5f..3d505e093b8 100644 --- a/test/cpp/ext/csm/BUILD +++ b/test/cpp/ext/csm/BUILD @@ -36,6 +36,8 @@ grpc_cc_test( ], deps = [ "//:grpc++", + "//:grpcpp_csm_observability", + "//:grpcpp_otel_plugin", "//src/cpp/ext/csm:csm_observability", "//src/cpp/ext/otel:otel_plugin", "//test/core/util:grpc_test_util", diff --git a/test/cpp/ext/csm/csm_observability_test.cc b/test/cpp/ext/csm/csm_observability_test.cc index 54e3e5c66cf..c6825c82846 100644 --- a/test/cpp/ext/csm/csm_observability_test.cc +++ b/test/cpp/ext/csm/csm_observability_test.cc @@ -22,6 +22,7 @@ #include "gtest/gtest.h" #include +#include #include "src/core/lib/gprpp/env.h" #include "test/core/util/test_config.h" @@ -62,6 +63,12 @@ TEST(CsmChannelTargetSelectorTest, XdsTargetsWithTDAuthority) { "xds://traffic-director-global.xds.googleapis.com/foo")); } +TEST(CsmPluginOptionTest, Basic) { + experimental::OpenTelemetryPluginBuilder() + .AddPluginOption(experimental::MakeCsmOpenTelemetryPluginOption()) + .BuildAndRegisterGlobal(); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/ext/otel/otel_plugin_test.cc b/test/cpp/ext/otel/otel_plugin_test.cc index e763cd7cad0..994ed6ce9d6 100644 --- a/test/cpp/ext/otel/otel_plugin_test.cc +++ b/test/cpp/ext/otel/otel_plugin_test.cc @@ -653,6 +653,282 @@ TEST_F(OpenTelemetryPluginEnd2EndTest, EXPECT_EQ(*status_value, "UNIMPLEMENTED"); } +using OpenTelemetryPluginOptionEnd2EndTest = OpenTelemetryPluginEnd2EndTest; + +class SimpleLabelIterable : public grpc::internal::LabelsIterable { + public: + explicit SimpleLabelIterable( + std::pair label) + : label_(label) {} + + absl::optional> Next() + override { + if (iterated_) { + return absl::nullopt; + } + iterated_ = true; + return label_; + } + + size_t Size() const override { return 1; } + + void ResetIteratorPosition() override { iterated_ = false; } + + private: + bool iterated_ = false; + std::pair label_; +}; + +class CustomLabelInjector : public grpc::internal::LabelsInjector { + public: + explicit CustomLabelInjector(std::pair label) + : label_(std::move(label)) {} + ~CustomLabelInjector() override {} + + std::unique_ptr GetLabels( + grpc_metadata_batch* /*incoming_initial_metadata*/) const override { + return std::make_unique(label_); + } + + void AddLabels( + grpc_metadata_batch* /*outgoing_initial_metadata*/, + grpc::internal::LabelsIterable* /*labels_from_incoming_metadata*/) + const override {} + + private: + std::pair label_; +}; + +class CustomPluginOption + : public grpc::internal::InternalOpenTelemetryPluginOption { + public: + CustomPluginOption(bool enabled_on_client, bool enabled_on_server, + std::pair label) + : enabled_on_client_(enabled_on_client), + enabled_on_server_(enabled_on_server), + label_injector_( + std::make_unique(std::move(label))) {} + + ~CustomPluginOption() override {} + + bool IsActiveOnClientChannel(absl::string_view /*target*/) const override { + return enabled_on_client_; + } + + bool IsActiveOnServer(const grpc_core::ChannelArgs& /*args*/) const override { + return enabled_on_server_; + } + + const grpc::internal::LabelsInjector* labels_injector() const override { + return label_injector_.get(); + } + + private: + bool enabled_on_client_; + bool enabled_on_server_; + std::unique_ptr label_injector_; +}; + +TEST_F(OpenTelemetryPluginOptionEnd2EndTest, Basic) { + std::vector< + std::unique_ptr> + plugin_option_list; + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ true, /*enabled_on_server*/ true, + std::make_pair("key", "value"))); + Init({grpc::experimental::OpenTelemetryPluginBuilder:: + kClientAttemptDurationInstrumentName, + grpc::experimental::OpenTelemetryPluginBuilder:: + kServerCallDurationInstrumentName}, + /*resource=*/opentelemetry::sdk::resource::Resource::Create({}), + /*labels_injector=*/nullptr, + /*test_no_meter_provider=*/false, + /*target_selector=*/absl::AnyInvocable(), + /*target_attribute_filter=*/ + absl::AnyInvocable(), + /*generic_method_attribute_filter=*/ + absl::AnyInvocable(), + /*plugin_options=*/std::move(plugin_option_list)); + SendRPC(); + auto data = ReadCurrentMetricsData( + [&](const absl::flat_hash_map< + std::string, + std::vector>& + data) { + return !data.contains("grpc.client.attempt.duration") || + !data.contains("grpc.server.call.duration"); + }); + // Verify client side metric + ASSERT_EQ(data["grpc.client.attempt.duration"].size(), 1); + const auto& client_attributes = + data["grpc.client.attempt.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(client_attributes.size(), 4); + EXPECT_EQ(absl::get(client_attributes.at("key")), "value"); + // Verify server side metric + ASSERT_EQ(data["grpc.server.call.duration"].size(), 1); + const auto& server_attributes = + data["grpc.server.call.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(server_attributes.size(), 3); + EXPECT_EQ(absl::get(server_attributes.at("key")), "value"); +} + +TEST_F(OpenTelemetryPluginOptionEnd2EndTest, ClientOnlyPluginOption) { + std::vector< + std::unique_ptr> + plugin_option_list; + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ true, /*enabled_on_server*/ false, + std::make_pair("key", "value"))); + Init({grpc::experimental::OpenTelemetryPluginBuilder:: + kClientAttemptDurationInstrumentName, + grpc::experimental::OpenTelemetryPluginBuilder:: + kServerCallDurationInstrumentName}, + /*resource=*/opentelemetry::sdk::resource::Resource::Create({}), + /*labels_injector=*/nullptr, + /*test_no_meter_provider=*/false, + /*target_selector=*/absl::AnyInvocable(), + /*target_attribute_filter=*/ + absl::AnyInvocable(), + /*generic_method_attribute_filter=*/ + absl::AnyInvocable(), + /*plugin_options=*/std::move(plugin_option_list)); + SendRPC(); + auto data = ReadCurrentMetricsData( + [&](const absl::flat_hash_map< + std::string, + std::vector>& + data) { + return !data.contains("grpc.client.attempt.duration") || + !data.contains("grpc.server.call.duration"); + }); + // Verify client side metric + ASSERT_EQ(data["grpc.client.attempt.duration"].size(), 1); + const auto& client_attributes = + data["grpc.client.attempt.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(client_attributes.size(), 4); + EXPECT_EQ(absl::get(client_attributes.at("key")), "value"); + // Verify server side metric + ASSERT_EQ(data["grpc.server.call.duration"].size(), 1); + const auto& server_attributes = + data["grpc.server.call.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(server_attributes.size(), 2); + EXPECT_THAT(server_attributes, + ::testing::Not(::testing::Contains(::testing::Key("key")))); +} + +TEST_F(OpenTelemetryPluginOptionEnd2EndTest, ServerOnlyPluginOption) { + std::vector< + std::unique_ptr> + plugin_option_list; + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ false, /*enabled_on_server*/ true, + std::make_pair("key", "value"))); + Init({grpc::experimental::OpenTelemetryPluginBuilder:: + kClientAttemptDurationInstrumentName, + grpc::experimental::OpenTelemetryPluginBuilder:: + kServerCallDurationInstrumentName}, + /*resource=*/opentelemetry::sdk::resource::Resource::Create({}), + /*labels_injector=*/nullptr, + /*test_no_meter_provider=*/false, + /*target_selector=*/absl::AnyInvocable(), + /*target_attribute_filter=*/ + absl::AnyInvocable(), + /*generic_method_attribute_filter=*/ + absl::AnyInvocable(), + /*plugin_options=*/std::move(plugin_option_list)); + SendRPC(); + auto data = ReadCurrentMetricsData( + [&](const absl::flat_hash_map< + std::string, + std::vector>& + data) { + return !data.contains("grpc.client.attempt.duration") || + !data.contains("grpc.server.call.duration"); + }); + // Verify client side metric + ASSERT_EQ(data["grpc.client.attempt.duration"].size(), 1); + const auto& attributes = + data["grpc.client.attempt.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(attributes.size(), 3); + EXPECT_THAT(attributes, + ::testing::Not(::testing::Contains(::testing::Key("key")))); + // Verify server side metric + ASSERT_EQ(data["grpc.server.call.duration"].size(), 1); + const auto& server_attributes = + data["grpc.server.call.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(server_attributes.size(), 3); + EXPECT_EQ(absl::get(server_attributes.at("key")), "value"); +} + +TEST_F(OpenTelemetryPluginOptionEnd2EndTest, + MultipleEnabledAndDisabledPluginOptions) { + std::vector< + std::unique_ptr> + plugin_option_list; + plugin_option_list.reserve(5); + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ true, /*enabled_on_server*/ true, + std::make_pair("key1", "value1"))); + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ true, /*enabled_on_server*/ false, + std::make_pair("key2", "value2"))); + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ true, /*enabled_on_server*/ false, + std::make_pair("key3", "value3"))); + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ false, /*enabled_on_server*/ true, + std::make_pair("key4", "value4"))); + plugin_option_list.emplace_back(std::make_unique( + /*enabled_on_client*/ false, /*enabled_on_server*/ true, + std::make_pair("key5", "value5"))); + Init({grpc::experimental::OpenTelemetryPluginBuilder:: + kClientAttemptDurationInstrumentName, + grpc::experimental::OpenTelemetryPluginBuilder:: + kServerCallDurationInstrumentName}, + /*resource=*/opentelemetry::sdk::resource::Resource::Create({}), + /*labels_injector=*/nullptr, + /*test_no_meter_provider=*/false, + /*target_selector=*/absl::AnyInvocable(), + /*target_attribute_filter=*/ + absl::AnyInvocable(), + /*generic_method_attribute_filter=*/ + absl::AnyInvocable(), + /*plugin_options=*/std::move(plugin_option_list)); + SendRPC(); + auto data = ReadCurrentMetricsData( + [&](const absl::flat_hash_map< + std::string, + std::vector>& + data) { + return !data.contains("grpc.client.attempt.duration") || + !data.contains("grpc.server.call.duration"); + }); + // Verify client side metric + ASSERT_EQ(data["grpc.client.attempt.duration"].size(), 1); + const auto& client_attributes = + data["grpc.client.attempt.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(client_attributes.size(), 6); + EXPECT_EQ(absl::get(client_attributes.at("key1")), "value1"); + EXPECT_EQ(absl::get(client_attributes.at("key2")), "value2"); + EXPECT_EQ(absl::get(client_attributes.at("key3")), "value3"); + EXPECT_THAT(client_attributes, + ::testing::Not(::testing::Contains(::testing::Key("key4")))); + EXPECT_THAT(client_attributes, + ::testing::Not(::testing::Contains(::testing::Key("key5")))); + // Verify server side metric + ASSERT_EQ(data["grpc.server.call.duration"].size(), 1); + const auto& server_attributes = + data["grpc.server.call.duration"][0].attributes.GetAttributes(); + EXPECT_EQ(server_attributes.size(), 5); + EXPECT_EQ(absl::get(server_attributes.at("key1")), "value1"); + EXPECT_THAT(server_attributes, + ::testing::Not(::testing::Contains(::testing::Key("key2")))); + EXPECT_THAT(server_attributes, + ::testing::Not(::testing::Contains(::testing::Key("key3")))); + EXPECT_EQ(absl::get(server_attributes.at("key4")), "value4"); + EXPECT_EQ(absl::get(server_attributes.at("key5")), "value5"); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/ext/otel/otel_test_library.cc b/test/cpp/ext/otel/otel_test_library.cc index bf530017bf9..53aa350435f 100644 --- a/test/cpp/ext/otel/otel_test_library.cc +++ b/test/cpp/ext/otel/otel_test_library.cc @@ -48,7 +48,10 @@ void OpenTelemetryPluginEnd2EndTest::Init( absl::AnyInvocable target_attribute_filter, absl::AnyInvocable - generic_method_attribute_filter) { + generic_method_attribute_filter, + std::vector< + std::unique_ptr> + plugin_options) { // We are resetting the MeterProvider and OpenTelemetry plugin at the start // of each test to avoid test results from one test carrying over to another // test. (Some measurements can get arbitrarily delayed.) @@ -76,6 +79,9 @@ void OpenTelemetryPluginEnd2EndTest::Init( ot_builder.SetTargetAttributeFilter(std::move(target_attribute_filter)); ot_builder.SetGenericMethodAttributeFilter( std::move(generic_method_attribute_filter)); + for (auto& option : plugin_options) { + ot_builder.AddPluginOption(std::move(option)); + } ot_builder.BuildAndRegisterGlobal(); grpc_init(); grpc::ServerBuilder builder; diff --git a/test/cpp/ext/otel/otel_test_library.h b/test/cpp/ext/otel/otel_test_library.h index 1076d29d1b3..629d8c12762 100644 --- a/test/cpp/ext/otel/otel_test_library.h +++ b/test/cpp/ext/otel/otel_test_library.h @@ -70,7 +70,10 @@ class OpenTelemetryPluginEnd2EndTest : public ::testing::Test { absl::AnyInvocable(), absl::AnyInvocable generic_method_attribute_filter = absl::AnyInvocable< - bool(absl::string_view /*generic_method*/) const>()); + bool(absl::string_view /*generic_method*/) const>(), + std::vector< + std::unique_ptr> + plugin_options = {}); void TearDown() override; diff --git a/test/cpp/interop/observability_client.cc b/test/cpp/interop/observability_client.cc index a815f090946..259b47dd124 100644 --- a/test/cpp/interop/observability_client.cc +++ b/test/cpp/interop/observability_client.cc @@ -30,10 +30,10 @@ #include #include #include +#include #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/crash.h" -#include "src/cpp/ext/otel/otel_plugin.h" #include "test/core/util/test_config.h" #include "test/cpp/interop/client_helper.h" #include "test/cpp/interop/interop_client.h" @@ -236,7 +236,7 @@ int main(int argc, char** argv) { auto meter_provider = std::make_shared(); meter_provider->AddMetricReader(std::move(prometheus_exporter)); - grpc::internal::OpenTelemetryPluginBuilderImpl otel_builder; + grpc::experimental::OpenTelemetryPluginBuilder otel_builder; otel_builder.SetMeterProvider(std::move(meter_provider)); otel_builder.BuildAndRegisterGlobal(); } From d8ae1d28c50bba7e4ded076c35bf2b51d01b763c Mon Sep 17 00:00:00 2001 From: Xuan Wang Date: Tue, 9 Jan 2024 18:03:13 +0000 Subject: [PATCH 16/27] [Python O11Y] Add _registered_method to __init__.py (#35482) Closes #35482 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35482 from XuanWang-Amos:fix_registered_method 49321c83b8da361377511ae53127c369518eb4f9 PiperOrigin-RevId: 596967469 --- src/python/grpcio/grpc/__init__.py | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 9f07579ab86..f66cbc0d635 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1000,7 +1000,11 @@ class Channel(abc.ABC): @abc.abstractmethod def unary_unary( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): """Creates a UnaryUnaryMultiCallable for a unary-unary method. @@ -1011,6 +1015,8 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. + _registered_method: Internal Only. A bool representing whether the method + is registered. Returns: A UnaryUnaryMultiCallable value for the named unary-unary method. @@ -1019,7 +1025,11 @@ class Channel(abc.ABC): @abc.abstractmethod def unary_stream( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): """Creates a UnaryStreamMultiCallable for a unary-stream method. @@ -1030,6 +1040,8 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. + _registered_method: Internal Only. A bool representing whether the method + is registered. Returns: A UnaryStreamMultiCallable value for the name unary-stream method. @@ -1038,7 +1050,11 @@ class Channel(abc.ABC): @abc.abstractmethod def stream_unary( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): """Creates a StreamUnaryMultiCallable for a stream-unary method. @@ -1049,6 +1065,8 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. + _registered_method: Internal Only. A bool representing whether the method + is registered. Returns: A StreamUnaryMultiCallable value for the named stream-unary method. @@ -1057,7 +1075,11 @@ class Channel(abc.ABC): @abc.abstractmethod def stream_stream( - self, method, request_serializer=None, response_deserializer=None + self, + method, + request_serializer=None, + response_deserializer=None, + _registered_method=False, ): """Creates a StreamStreamMultiCallable for a stream-stream method. @@ -1068,6 +1090,8 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. + _registered_method: Internal Only. A bool representing whether the method + is registered. Returns: A StreamStreamMultiCallable value for the named stream-stream method. From 745a61222d578d9c1d2fa22b314b792b2056ba9e Mon Sep 17 00:00:00 2001 From: AJ Heller Date: Tue, 9 Jan 2024 10:44:49 -0800 Subject: [PATCH 17/27] [EventEngine] Implement Windows Native Resolver (#35458) Closes #35458 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35458 from drfloob:windows-native-ee-resolver 364b7103424f0b15d44d4385fd2ea0d323ab6b47 PiperOrigin-RevId: 596981099 --- CMakeLists.txt | 4 + Makefile | 2 + Package.swift | 2 + build_autogenerated.yaml | 8 ++ config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 3 + package.xml | 2 + src/core/BUILD | 14 +++ .../windows/native_windows_dns_resolver.cc | 114 ++++++++++++++++++ .../windows/native_windows_dns_resolver.h | 51 ++++++++ .../event_engine/windows/windows_engine.cc | 8 +- src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 2 + 18 files changed, 218 insertions(+), 4 deletions(-) create mode 100644 src/core/lib/event_engine/windows/native_windows_dns_resolver.cc create mode 100644 src/core/lib/event_engine/windows/native_windows_dns_resolver.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d178f90137..ab169d9afd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2280,6 +2280,7 @@ add_library(grpc src/core/lib/event_engine/utils.cc src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc src/core/lib/event_engine/windows/iocp.cc + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc src/core/lib/event_engine/windows/win_socket.cc src/core/lib/event_engine/windows/windows_endpoint.cc src/core/lib/event_engine/windows/windows_engine.cc @@ -3011,6 +3012,7 @@ add_library(grpc_unsecure src/core/lib/event_engine/utils.cc src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc src/core/lib/event_engine/windows/iocp.cc + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc src/core/lib/event_engine/windows/win_socket.cc src/core/lib/event_engine/windows/windows_endpoint.cc src/core/lib/event_engine/windows/windows_engine.cc @@ -5000,6 +5002,7 @@ add_library(grpc_authorization_provider src/core/lib/event_engine/utils.cc src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc src/core/lib/event_engine/windows/iocp.cc + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc src/core/lib/event_engine/windows/win_socket.cc src/core/lib/event_engine/windows/windows_endpoint.cc src/core/lib/event_engine/windows/windows_engine.cc @@ -24761,6 +24764,7 @@ add_executable(test_core_transport_chaotic_good_frame_test src/core/lib/event_engine/utils.cc src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc src/core/lib/event_engine/windows/iocp.cc + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc src/core/lib/event_engine/windows/win_socket.cc src/core/lib/event_engine/windows/windows_endpoint.cc src/core/lib/event_engine/windows/windows_engine.cc diff --git a/Makefile b/Makefile index 0071fee977c..b7224ba266b 100644 --- a/Makefile +++ b/Makefile @@ -1480,6 +1480,7 @@ LIBGRPC_SRC = \ src/core/lib/event_engine/utils.cc \ src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \ src/core/lib/event_engine/windows/iocp.cc \ + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \ src/core/lib/event_engine/windows/win_socket.cc \ src/core/lib/event_engine/windows/windows_endpoint.cc \ src/core/lib/event_engine/windows/windows_engine.cc \ @@ -2061,6 +2062,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/event_engine/utils.cc \ src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \ src/core/lib/event_engine/windows/iocp.cc \ + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \ src/core/lib/event_engine/windows/win_socket.cc \ src/core/lib/event_engine/windows/windows_endpoint.cc \ src/core/lib/event_engine/windows/windows_engine.cc \ diff --git a/Package.swift b/Package.swift index 1f8a60eb738..06646df8e87 100644 --- a/Package.swift +++ b/Package.swift @@ -1341,6 +1341,8 @@ let package = Package( "src/core/lib/event_engine/windows/grpc_polled_fd_windows.h", "src/core/lib/event_engine/windows/iocp.cc", "src/core/lib/event_engine/windows/iocp.h", + "src/core/lib/event_engine/windows/native_windows_dns_resolver.cc", + "src/core/lib/event_engine/windows/native_windows_dns_resolver.h", "src/core/lib/event_engine/windows/win_socket.cc", "src/core/lib/event_engine/windows/win_socket.h", "src/core/lib/event_engine/windows/windows_endpoint.cc", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 46cd87ce1d7..92437f0ce8a 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -911,6 +911,7 @@ libs: - src/core/lib/event_engine/utils.h - src/core/lib/event_engine/windows/grpc_polled_fd_windows.h - src/core/lib/event_engine/windows/iocp.h + - src/core/lib/event_engine/windows/native_windows_dns_resolver.h - src/core/lib/event_engine/windows/win_socket.h - src/core/lib/event_engine/windows/windows_endpoint.h - src/core/lib/event_engine/windows/windows_engine.h @@ -1739,6 +1740,7 @@ libs: - src/core/lib/event_engine/utils.cc - src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc - src/core/lib/event_engine/windows/iocp.cc + - src/core/lib/event_engine/windows/native_windows_dns_resolver.cc - src/core/lib/event_engine/windows/win_socket.cc - src/core/lib/event_engine/windows/windows_endpoint.cc - src/core/lib/event_engine/windows/windows_engine.cc @@ -2376,6 +2378,7 @@ libs: - src/core/lib/event_engine/utils.h - src/core/lib/event_engine/windows/grpc_polled_fd_windows.h - src/core/lib/event_engine/windows/iocp.h + - src/core/lib/event_engine/windows/native_windows_dns_resolver.h - src/core/lib/event_engine/windows/win_socket.h - src/core/lib/event_engine/windows/windows_endpoint.h - src/core/lib/event_engine/windows/windows_engine.h @@ -2827,6 +2830,7 @@ libs: - src/core/lib/event_engine/utils.cc - src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc - src/core/lib/event_engine/windows/iocp.cc + - src/core/lib/event_engine/windows/native_windows_dns_resolver.cc - src/core/lib/event_engine/windows/win_socket.cc - src/core/lib/event_engine/windows/windows_endpoint.cc - src/core/lib/event_engine/windows/windows_engine.cc @@ -4518,6 +4522,7 @@ libs: - src/core/lib/event_engine/utils.h - src/core/lib/event_engine/windows/grpc_polled_fd_windows.h - src/core/lib/event_engine/windows/iocp.h + - src/core/lib/event_engine/windows/native_windows_dns_resolver.h - src/core/lib/event_engine/windows/win_socket.h - src/core/lib/event_engine/windows/windows_endpoint.h - src/core/lib/event_engine/windows/windows_engine.h @@ -4875,6 +4880,7 @@ libs: - src/core/lib/event_engine/utils.cc - src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc - src/core/lib/event_engine/windows/iocp.cc + - src/core/lib/event_engine/windows/native_windows_dns_resolver.cc - src/core/lib/event_engine/windows/win_socket.cc - src/core/lib/event_engine/windows/windows_endpoint.cc - src/core/lib/event_engine/windows/windows_engine.cc @@ -16924,6 +16930,7 @@ targets: - src/core/lib/event_engine/utils.h - src/core/lib/event_engine/windows/grpc_polled_fd_windows.h - src/core/lib/event_engine/windows/iocp.h + - src/core/lib/event_engine/windows/native_windows_dns_resolver.h - src/core/lib/event_engine/windows/win_socket.h - src/core/lib/event_engine/windows/windows_endpoint.h - src/core/lib/event_engine/windows/windows_engine.h @@ -17262,6 +17269,7 @@ targets: - src/core/lib/event_engine/utils.cc - src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc - src/core/lib/event_engine/windows/iocp.cc + - src/core/lib/event_engine/windows/native_windows_dns_resolver.cc - src/core/lib/event_engine/windows/win_socket.cc - src/core/lib/event_engine/windows/windows_endpoint.cc - src/core/lib/event_engine/windows/windows_engine.cc diff --git a/config.m4 b/config.m4 index 34b99719662..74d0f802315 100644 --- a/config.m4 +++ b/config.m4 @@ -570,6 +570,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/event_engine/utils.cc \ src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \ src/core/lib/event_engine/windows/iocp.cc \ + src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \ src/core/lib/event_engine/windows/win_socket.cc \ src/core/lib/event_engine/windows/windows_endpoint.cc \ src/core/lib/event_engine/windows/windows_engine.cc \ diff --git a/config.w32 b/config.w32 index d7678fff5ac..afc9589aed3 100644 --- a/config.w32 +++ b/config.w32 @@ -535,6 +535,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\event_engine\\utils.cc " + "src\\core\\lib\\event_engine\\windows\\grpc_polled_fd_windows.cc " + "src\\core\\lib\\event_engine\\windows\\iocp.cc " + + "src\\core\\lib\\event_engine\\windows\\native_windows_dns_resolver.cc " + "src\\core\\lib\\event_engine\\windows\\win_socket.cc " + "src\\core\\lib\\event_engine\\windows\\windows_endpoint.cc " + "src\\core\\lib\\event_engine\\windows\\windows_engine.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ff49bb43910..0c39f744fb0 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -984,6 +984,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/utils.h', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h', 'src/core/lib/event_engine/windows/iocp.h', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.h', 'src/core/lib/event_engine/windows/win_socket.h', 'src/core/lib/event_engine/windows/windows_endpoint.h', 'src/core/lib/event_engine/windows/windows_engine.h', @@ -2225,6 +2226,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/utils.h', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h', 'src/core/lib/event_engine/windows/iocp.h', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.h', 'src/core/lib/event_engine/windows/win_socket.h', 'src/core/lib/event_engine/windows/windows_endpoint.h', 'src/core/lib/event_engine/windows/windows_engine.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index bebce4fc733..a700bdbec44 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1444,6 +1444,8 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h', 'src/core/lib/event_engine/windows/iocp.cc', 'src/core/lib/event_engine/windows/iocp.h', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.h', 'src/core/lib/event_engine/windows/win_socket.cc', 'src/core/lib/event_engine/windows/win_socket.h', 'src/core/lib/event_engine/windows/windows_endpoint.cc', @@ -2991,6 +2993,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/utils.h', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h', 'src/core/lib/event_engine/windows/iocp.h', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.h', 'src/core/lib/event_engine/windows/win_socket.h', 'src/core/lib/event_engine/windows/windows_endpoint.h', 'src/core/lib/event_engine/windows/windows_engine.h', diff --git a/grpc.gemspec b/grpc.gemspec index 4a2e017e484..bfd2ac83bca 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1347,6 +1347,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/event_engine/windows/grpc_polled_fd_windows.h ) s.files += %w( src/core/lib/event_engine/windows/iocp.cc ) s.files += %w( src/core/lib/event_engine/windows/iocp.h ) + s.files += %w( src/core/lib/event_engine/windows/native_windows_dns_resolver.cc ) + s.files += %w( src/core/lib/event_engine/windows/native_windows_dns_resolver.h ) s.files += %w( src/core/lib/event_engine/windows/win_socket.cc ) s.files += %w( src/core/lib/event_engine/windows/win_socket.h ) s.files += %w( src/core/lib/event_engine/windows/windows_endpoint.cc ) diff --git a/grpc.gyp b/grpc.gyp index 3a5ba2d57d0..1a33c9eb586 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -799,6 +799,7 @@ 'src/core/lib/event_engine/utils.cc', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', 'src/core/lib/event_engine/windows/win_socket.cc', 'src/core/lib/event_engine/windows/windows_endpoint.cc', 'src/core/lib/event_engine/windows/windows_engine.cc', @@ -1321,6 +1322,7 @@ 'src/core/lib/event_engine/utils.cc', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', 'src/core/lib/event_engine/windows/win_socket.cc', 'src/core/lib/event_engine/windows/windows_endpoint.cc', 'src/core/lib/event_engine/windows/windows_engine.cc', @@ -2100,6 +2102,7 @@ 'src/core/lib/event_engine/utils.cc', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', 'src/core/lib/event_engine/windows/win_socket.cc', 'src/core/lib/event_engine/windows/windows_endpoint.cc', 'src/core/lib/event_engine/windows/windows_engine.cc', diff --git a/package.xml b/package.xml index 67d5577eff9..885bedac415 100644 --- a/package.xml +++ b/package.xml @@ -1329,6 +1329,8 @@ + + diff --git a/src/core/BUILD b/src/core/BUILD index 776a390ff0d..37a65c4b32b 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2222,6 +2222,20 @@ grpc_cc_library( "windows_endpoint", "windows_event_engine_listener", "windows_iocp", + "windows_native_resolver", + "//:event_engine_base_hdrs", + "//:gpr", + ], +) + +grpc_cc_library( + name = "windows_native_resolver", + srcs = ["lib/event_engine/windows/native_windows_dns_resolver.cc"], + hdrs = ["lib/event_engine/windows/native_windows_dns_resolver.h"], + external_deps = ["absl/strings:str_format"], + deps = [ + "error", + "status_helper", "//:event_engine_base_hdrs", "//:gpr", ], diff --git a/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc b/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc new file mode 100644 index 00000000000..a00ed40225b --- /dev/null +++ b/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc @@ -0,0 +1,114 @@ +// 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. +#include + +#ifdef GPR_WINDOWS +#include +#include +#include + +#include + +#include "absl/strings/str_format.h" + +#include + +#include "src/core/lib/event_engine/windows/native_windows_dns_resolver.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/status_helper.h" +#include "src/core/lib/iomgr/error.h" + +namespace grpc_event_engine { +namespace experimental { + +namespace { +absl::StatusOr> +LookupHostnameBlocking(absl::string_view name, absl::string_view default_port) { + std::vector addresses; + // parse name, splitting it into host and port parts + std::string host; + std::string port; + grpc_core::SplitHostPort(name, &host, &port); + if (host.empty()) { + return absl::InvalidArgumentError(absl::StrCat("Unparseable name: ", name)); + } + if (port.empty()) { + if (default_port.empty()) { + return absl::InvalidArgumentError( + absl::StrFormat("No port in name %s or default_port argument", name)); + } + port = std::string(default_port); + } + // Call getaddrinfo + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // ipv4 or ipv6 + hints.ai_socktype = SOCK_STREAM; // stream socket + hints.ai_flags = AI_PASSIVE; // for wildcard IP address + struct addrinfo* result = nullptr; + int getaddrinfo_error = + getaddrinfo(host.c_str(), port.c_str(), &hints, &result); + if (getaddrinfo_error != 0) { + return absl::UnknownError( + absl::StrFormat("Address lookup failed for %s os_error: %s", name, + grpc_core::StatusToString( + GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo")) + .c_str())); + } + // Success path: collect and return all addresses + for (auto* resp = result; resp != nullptr; resp = resp->ai_next) { + addresses.emplace_back(resp->ai_addr, resp->ai_addrlen); + } + if (result) freeaddrinfo(result); + return addresses; +} + +} // namespace +NativeWindowsDNSResolver::NativeWindowsDNSResolver( + std::shared_ptr event_engine) + : event_engine_(std::move(event_engine)) {} + +void NativeWindowsDNSResolver::LookupHostname( + EventEngine::DNSResolver::LookupHostnameCallback on_resolved, + absl::string_view name, absl::string_view default_port) { + event_engine_->Run( + [name, default_port, on_resolved = std::move(on_resolved)]() mutable { + on_resolved(LookupHostnameBlocking(name, default_port)); + }); +} + +void NativeWindowsDNSResolver::LookupSRV( + EventEngine::DNSResolver::LookupSRVCallback on_resolved, + absl::string_view /* name */) { + // Not supported + event_engine_->Run([on_resolved = std::move(on_resolved)]() mutable { + on_resolved(absl::UnimplementedError( + "The Native resolver does not support looking up SRV records")); + }); +} + +void NativeWindowsDNSResolver::LookupTXT( + EventEngine::DNSResolver::LookupTXTCallback on_resolved, + absl::string_view /* name */) { + // Not supported + event_engine_->Run([on_resolved = std::move(on_resolved)]() mutable { + on_resolved(absl::UnimplementedError( + "The Native resolver does not support looking up TXT records")); + }); +} + +} // namespace experimental +} // namespace grpc_event_engine + +#endif // GPR_WINDOWS diff --git a/src/core/lib/event_engine/windows/native_windows_dns_resolver.h b/src/core/lib/event_engine/windows/native_windows_dns_resolver.h new file mode 100644 index 00000000000..43d1fe27fcc --- /dev/null +++ b/src/core/lib/event_engine/windows/native_windows_dns_resolver.h @@ -0,0 +1,51 @@ +// 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_SRC_CORE_LIB_EVENT_ENGINE_WINDOWS_NATIVE_WINDOWS_DNS_RESOLVER_H +#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_WINDOWS_NATIVE_WINDOWS_DNS_RESOLVER_H + +#include + +#ifdef GPR_WINDOWS + +#include + +namespace grpc_event_engine { +namespace experimental { + +// An asynchronous DNS resolver which uses the native platform's getaddrinfo +// API. Only supports A/AAAA records. +class NativeWindowsDNSResolver : public EventEngine::DNSResolver { + public: + explicit NativeWindowsDNSResolver(std::shared_ptr event_engine); + + void LookupHostname( + EventEngine::DNSResolver::LookupHostnameCallback on_resolved, + absl::string_view name, absl::string_view default_port) override; + + void LookupSRV(EventEngine::DNSResolver::LookupSRVCallback on_resolved, + absl::string_view name) override; + + void LookupTXT(EventEngine::DNSResolver::LookupTXTCallback on_resolved, + absl::string_view name) override; + + private: + std::shared_ptr event_engine_; +}; + +} // namespace experimental +} // namespace grpc_event_engine + +#endif + +#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_WINDOWS_NATIVE_WINDOWS_DNS_RESOLVER_H diff --git a/src/core/lib/event_engine/windows/windows_engine.cc b/src/core/lib/event_engine/windows/windows_engine.cc index 25120267039..69e4963f387 100644 --- a/src/core/lib/event_engine/windows/windows_engine.cc +++ b/src/core/lib/event_engine/windows/windows_engine.cc @@ -37,6 +37,7 @@ #include "src/core/lib/event_engine/utils.h" #include "src/core/lib/event_engine/windows/grpc_polled_fd_windows.h" #include "src/core/lib/event_engine/windows/iocp.h" +#include "src/core/lib/event_engine/windows/native_windows_dns_resolver.h" #include "src/core/lib/event_engine/windows/windows_endpoint.h" #include "src/core/lib/event_engine/windows/windows_engine.h" #include "src/core/lib/event_engine/windows/windows_listener.h" @@ -233,10 +234,9 @@ WindowsEventEngine::GetDNSResolver( return std::make_unique( std::move(*ares_resolver)); #else // GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) - // TODO(yijiem): Implement a basic A/AAAA-only native resolver in - // WindowsEventEngine. - (void)options; - grpc_core::Crash("unimplemented"); + GRPC_EVENT_ENGINE_DNS_TRACE( + "WindowsEventEngine:%p creating NativeWindowsDNSResolver", this); + return std::make_unique(shared_from_this()); #endif // GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 351065b21a8..30a62ced196 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -544,6 +544,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/event_engine/utils.cc', 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', 'src/core/lib/event_engine/windows/win_socket.cc', 'src/core/lib/event_engine/windows/windows_endpoint.cc', 'src/core/lib/event_engine/windows/windows_engine.cc', diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c0fc6f9e749..168ddf984d8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2346,6 +2346,8 @@ src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \ src/core/lib/event_engine/windows/grpc_polled_fd_windows.h \ src/core/lib/event_engine/windows/iocp.cc \ src/core/lib/event_engine/windows/iocp.h \ +src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \ +src/core/lib/event_engine/windows/native_windows_dns_resolver.h \ src/core/lib/event_engine/windows/win_socket.cc \ src/core/lib/event_engine/windows/win_socket.h \ src/core/lib/event_engine/windows/windows_endpoint.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1645a7c7c9a..8b439b3ac66 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -2122,6 +2122,8 @@ src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \ src/core/lib/event_engine/windows/grpc_polled_fd_windows.h \ src/core/lib/event_engine/windows/iocp.cc \ src/core/lib/event_engine/windows/iocp.h \ +src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \ +src/core/lib/event_engine/windows/native_windows_dns_resolver.h \ src/core/lib/event_engine/windows/win_socket.cc \ src/core/lib/event_engine/windows/win_socket.h \ src/core/lib/event_engine/windows/windows_endpoint.cc \ From 6872a7a47355128fe2c4ec17ed85f37cf9bdc848 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Jan 2024 11:20:43 -0800 Subject: [PATCH 18/27] Change some text to Implementation Private What was there trips some tooling and will cause some repo maintenance issues going forward PiperOrigin-RevId: 596992313 --- src/python/grpcio/grpc/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index f66cbc0d635..e0ec581f9d4 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1015,7 +1015,7 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. - _registered_method: Internal Only. A bool representing whether the method + _registered_method: Implementation Private. A bool representing whether the method is registered. Returns: @@ -1040,7 +1040,7 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. - _registered_method: Internal Only. A bool representing whether the method + _registered_method: Implementation Private. A bool representing whether the method is registered. Returns: @@ -1065,7 +1065,7 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. - _registered_method: Internal Only. A bool representing whether the method + _registered_method: Implementation Private. A bool representing whether the method is registered. Returns: @@ -1090,7 +1090,7 @@ class Channel(abc.ABC): response_deserializer: Optional :term:`deserializer` for deserializing the response message. Response goes undeserialized in case None is passed. - _registered_method: Internal Only. A bool representing whether the method + _registered_method: Implementation Private. A bool representing whether the method is registered. Returns: From 6eaec4f96e14a9171b84b5760d87e62956d28f3d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Jan 2024 12:09:07 -0800 Subject: [PATCH 19/27] [call-v3] Convert ServerConfigSelectorFilter (#35470) Closes #35470 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35470 from ctiller:scsf 789b365616d67a95659a6e60b6364855311e0085 PiperOrigin-RevId: 597006442 --- .../server_config_selector_filter.cc | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc b/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc index 3d9a23fcc7c..b79090ddab9 100644 --- a/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +++ b/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc @@ -47,7 +47,8 @@ namespace grpc_core { namespace { -class ServerConfigSelectorFilter final : public ChannelFilter { +class ServerConfigSelectorFilter final + : public ImplementChannelFilter { public: ~ServerConfigSelectorFilter() override; @@ -60,8 +61,16 @@ class ServerConfigSelectorFilter final : public ChannelFilter { static absl::StatusOr Create( const ChannelArgs& args, ChannelFilter::Args); - ArenaPromise MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) override; + class Call { + public: + absl::Status OnClientInitialMetadata(ClientMetadata& md, + ServerConfigSelectorFilter* filter); + static const NoInterceptor OnServerInitialMetadata; + static const NoInterceptor OnServerTrailingMetadata; + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + static const NoInterceptor OnFinalize; + }; absl::StatusOr> config_selector() { MutexLock lock(&state_->mu); @@ -130,25 +139,28 @@ ServerConfigSelectorFilter::~ServerConfigSelectorFilter() { } } -ArenaPromise ServerConfigSelectorFilter::MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) { - auto sel = config_selector(); - if (!sel.ok()) return Immediate(ServerMetadataFromStatus(sel.status())); - auto call_config = - sel.value()->GetCallConfig(call_args.client_initial_metadata.get()); +absl::Status ServerConfigSelectorFilter::Call::OnClientInitialMetadata( + ClientMetadata& md, ServerConfigSelectorFilter* filter) { + auto sel = filter->config_selector(); + if (!sel.ok()) return sel.status(); + auto call_config = sel.value()->GetCallConfig(&md); if (!call_config.ok()) { - auto r = Immediate(ServerMetadataFromStatus( - absl::UnavailableError(StatusToString(call_config.status())))); - return std::move(r); + return absl::UnavailableError(StatusToString(call_config.status())); } auto* service_config_call_data = GetContext()->New( GetContext(), GetContext()); service_config_call_data->SetServiceConfig( std::move(call_config->service_config), call_config->method_configs); - return next_promise_factory(std::move(call_args)); + return absl::OkStatus(); } +const NoInterceptor ServerConfigSelectorFilter::Call::OnServerInitialMetadata; +const NoInterceptor ServerConfigSelectorFilter::Call::OnServerTrailingMetadata; +const NoInterceptor ServerConfigSelectorFilter::Call::OnClientToServerMessage; +const NoInterceptor ServerConfigSelectorFilter::Call::OnServerToClientMessage; +const NoInterceptor ServerConfigSelectorFilter::Call::OnFinalize; + } // namespace const grpc_channel_filter kServerConfigSelectorFilter = From e73b76a7daf33d756cb06f90aa0e5ab4e088d889 Mon Sep 17 00:00:00 2001 From: Eugene Ostroukhov Date: Tue, 9 Jan 2024 12:11:19 -0800 Subject: [PATCH 20/27] [Test] Fix bug in waiting for the Orca OOB report (#35467) Make sure there is no unnecessary delays when there are multiple reports in the queue. This change also adds a test for the custom LB policy. Closes #35467 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35467 from eugeneo:tasks/orca-test-timeout-316026521 4aab50a1187586ce1375bc85231b70091ef9d3e2 PiperOrigin-RevId: 597007131 --- CMakeLists.txt | 50 ++++++ build_autogenerated.yaml | 18 ++ test/cpp/interop/BUILD | 16 ++ test/cpp/interop/backend_metrics_lb_policy.cc | 15 +- .../interop/backend_metrics_lb_policy_test.cc | 159 ++++++++++++++++++ test/cpp/interop/interop_client.cc | 10 +- tools/run_tests/generated/tests.json | 24 +++ 7 files changed, 284 insertions(+), 8 deletions(-) create mode 100644 test/cpp/interop/backend_metrics_lb_policy_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index ab169d9afd3..1dbc6db5e0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -880,6 +880,7 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_cxx avl_test) add_dependencies(buildtests_cxx aws_request_signer_test) add_dependencies(buildtests_cxx b64_test) + add_dependencies(buildtests_cxx backend_metrics_lb_policy_test) add_dependencies(buildtests_cxx backoff_test) add_dependencies(buildtests_cxx bad_ping_test) add_dependencies(buildtests_cxx bad_server_response_test) @@ -6853,6 +6854,55 @@ target_link_libraries(b64_test ) +endif() +if(gRPC_BUILD_TESTS) + +add_executable(backend_metrics_lb_policy_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + src/cpp/server/orca/orca_service.cc + test/cpp/interop/backend_metrics_lb_policy.cc + test/cpp/interop/backend_metrics_lb_policy_test.cc +) +target_compile_features(backend_metrics_lb_policy_test PUBLIC cxx_std_14) +target_include_directories(backend_metrics_lb_policy_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(backend_metrics_lb_policy_test + ${_gRPC_ALLTARGETS_LIBRARIES} + gtest + grpc++ + grpc_test_util + grpc++_test_config +) + + endif() if(gRPC_BUILD_TESTS) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 92437f0ce8a..9f9385d801d 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -5849,6 +5849,24 @@ targets: - gtest - grpc_test_util uses_polling: false +- name: backend_metrics_lb_policy_test + gtest: true + build: test + language: c++ + headers: + - test/cpp/interop/backend_metrics_lb_policy.h + src: + - src/proto/grpc/testing/empty.proto + - src/proto/grpc/testing/messages.proto + - src/proto/grpc/testing/test.proto + - src/cpp/server/orca/orca_service.cc + - test/cpp/interop/backend_metrics_lb_policy.cc + - test/cpp/interop/backend_metrics_lb_policy_test.cc + deps: + - gtest + - grpc++ + - grpc_test_util + - grpc++_test_config - name: backoff_test gtest: true build: test diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 8262b29ab27..6d5b80422c9 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -532,6 +532,22 @@ grpc_cc_library( ], ) +grpc_cc_test( + name = "backend_metrics_lb_policy_test", + srcs = [ + "backend_metrics_lb_policy_test.cc", + ], + external_deps = ["gtest"], + deps = [ + ":backend_metrics_lb_policy", + "//:grpc++", + "//:grpcpp_orca_service", + "//src/proto/grpc/testing:test_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + ], +) + grpc_cc_library( name = "rpc_behavior_lb_policy", srcs = [ diff --git a/test/cpp/interop/backend_metrics_lb_policy.cc b/test/cpp/interop/backend_metrics_lb_policy.cc index a10bd4f63a5..30f3bb18943 100644 --- a/test/cpp/interop/backend_metrics_lb_policy.cc +++ b/test/cpp/interop/backend_metrics_lb_policy.cc @@ -86,6 +86,11 @@ class BackendMetricsLbPolicy : public LoadBalancingPolicy { } absl::Status UpdateLocked(UpdateArgs args) override { + auto config = + CoreConfiguration::Get().lb_policy_registry().ParseLoadBalancingConfig( + grpc_core::Json::FromArray({grpc_core::Json::FromObject( + {{"pick_first", grpc_core::Json::FromObject({})}})})); + args.config = std::move(config.value()); return delegate_->UpdateLocked(std::move(args)); } @@ -249,14 +254,12 @@ LoadReportTracker::LoadReportEntry LoadReportTracker::WaitForOobLoadReport( grpc_core::MutexLock lock(&load_reports_mu_); // This condition will be called under lock for (size_t i = 0; i < max_attempts; i++) { - auto deadline = absl::Now() + poll_timeout; - // loop to handle spurious wakeups. - do { - if (absl::Now() >= deadline) { + if (oob_load_reports_.empty()) { + load_reports_cv_.WaitWithTimeout(&load_reports_mu_, poll_timeout); + if (oob_load_reports_.empty()) { return absl::nullopt; } - load_reports_cv_.WaitWithDeadline(&load_reports_mu_, deadline); - } while (oob_load_reports_.empty()); + } auto report = std::move(oob_load_reports_.front()); oob_load_reports_.pop_front(); if (predicate(report)) { diff --git a/test/cpp/interop/backend_metrics_lb_policy_test.cc b/test/cpp/interop/backend_metrics_lb_policy_test.cc new file mode 100644 index 00000000000..8ceae112fa8 --- /dev/null +++ b/test/cpp/interop/backend_metrics_lb_policy_test.cc @@ -0,0 +1,159 @@ +// +// +// 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 "test/cpp/interop/backend_metrics_lb_policy.h" + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/lib/config/config_vars.h" +#include "src/core/lib/gprpp/sync.h" +#include "src/proto/grpc/testing/messages.pb.h" +#include "src/proto/grpc/testing/test.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +namespace grpc { +namespace testing { +namespace { + +class EchoServiceImpl : public grpc::testing::TestService::CallbackService { + public: + grpc::ServerUnaryReactor* UnaryCall( + grpc::CallbackServerContext* context, + const grpc::testing::SimpleRequest* /* request */, + grpc::testing::SimpleResponse* /* response */) override { + auto reactor = context->DefaultReactor(); + reactor->Finish(grpc::Status::OK); + return reactor; + } +}; + +class Server { + public: + Server() : port_(grpc_pick_unused_port_or_die()) { + server_thread_ = std::thread(ServerLoop, this); + grpc_core::MutexLock lock(&mu_); + cond_.WaitWithTimeout(&mu_, absl::Seconds(1)); + } + + ~Server() { + server_->Shutdown(); + server_thread_.join(); + } + + std::string address() const { return absl::StrCat("localhost:", port_); } + + private: + static void ServerLoop(Server* server) { server->Run(); } + + void Run() { + ServerBuilder builder; + EchoServiceImpl service; + auto server_metric_recorder = + grpc::experimental::ServerMetricRecorder::Create(); + server_metric_recorder->SetCpuUtilization(.5f); + grpc::experimental::OrcaService orca_service( + server_metric_recorder.get(), + grpc::experimental::OrcaService::Options().set_min_report_duration( + absl::Seconds(1))); + builder.RegisterService(&orca_service); + builder.RegisterService(&service); + builder.AddListeningPort(address(), InsecureServerCredentials()); + auto grpc_server = builder.BuildAndStart(); + server_ = grpc_server.get(); + { + grpc_core::MutexLock lock(&mu_); + cond_.SignalAll(); + } + grpc_server->Wait(); + } + + int port_; + grpc_core::Mutex mu_; + grpc_core::CondVar cond_; + std::thread server_thread_; + grpc::Server* server_; +}; + +TEST(BackendMetricsLbPolicyTest, TestOobMetricsReceipt) { + LoadReportTracker tracker; + grpc_core::CoreConfiguration::RegisterBuilder(RegisterBackendMetricsLbPolicy); + Server server; + ChannelArguments args = tracker.GetChannelArguments(); + args.SetLoadBalancingPolicyName("test_backend_metrics_load_balancer"); + auto channel = grpc::CreateCustomChannel(server.address(), + InsecureChannelCredentials(), args); + auto stub = grpc::testing::TestService::Stub(channel); + ClientContext ctx; + SimpleRequest req; + SimpleResponse res; + grpc_core::Mutex mu; + grpc_core::CondVar cond; + absl::optional status; + + stub.async()->UnaryCall(&ctx, &req, &res, [&](auto s) { + grpc_core::MutexLock lock(&mu); + status = s; + cond.SignalAll(); + }); + // This report is sent on start, available immediately + auto report = tracker.WaitForOobLoadReport( + [](auto report) { return report.cpu_utilization() == 0.5; }, + absl::Milliseconds(1500), 3); + ASSERT_TRUE(report.has_value()); + EXPECT_EQ(report->cpu_utilization(), 0.5); + for (size_t i = 0; i < 3; i++) { + // Wait for slightly more than 1 min + report = tracker.WaitForOobLoadReport( + [](auto report) { return report.cpu_utilization() == 0.5; }, + absl::Milliseconds(1500), 3); + ASSERT_TRUE(report.has_value()); + EXPECT_EQ(report->cpu_utilization(), 0.5); + } + { + grpc_core::MutexLock lock(&mu); + if (!status.has_value()) { + cond.Wait(&mu); + } + ASSERT_TRUE(status.has_value()); + EXPECT_EQ(status->error_code(), grpc::StatusCode::OK); + } +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::TestEnvironment env(&argc, argv); + grpc_init(); + auto result = RUN_ALL_TESTS(); + grpc_shutdown(); + return result; +} diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 04bc8022d27..0185957408e 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -40,6 +40,7 @@ #include #include +#include "src/core/lib/config/config_vars.h" #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/gprpp/crash.h" #include "src/proto/grpc/testing/empty.pb.h" @@ -1022,8 +1023,13 @@ bool InteropClient::DoOrcaPerRpc() { bool InteropClient::DoOrcaOob() { static constexpr auto kTimeout = absl::Seconds(10); - gpr_log(GPR_DEBUG, "testing orca oob"); + gpr_log(GPR_INFO, "testing orca oob"); load_report_tracker_.ResetCollectedLoadReports(); + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + grpc_core::ConfigVars::Overrides overrides; + overrides.client_channel_backup_poll_interval_ms = 250; + grpc_core::ConfigVars::SetOverrides(overrides); grpc_core::CoreConfiguration::RegisterBuilder(RegisterBackendMetricsLbPolicy); ClientContext context; std::unique_ptr Date: Tue, 9 Jan 2024 12:12:33 -0800 Subject: [PATCH 21/27] [Test] Bumped the timeout of the cpp distrib tests to 60 mins (#35479) `distribtest.cpp_linux_x64_debian10_aarch64_cross_cmake_aarch64_cross` has been timed out recently about 50% hitting 45 min deadline so let's bump this to 60 mins. (The timeout for windows is bumped as well for consistency) Closes #35479 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35479 from veblush:long-cross-aarch64 8ad82d684cdc4ad655ec6cb9a22ed55cc6773544 PiperOrigin-RevId: 597007435 --- tools/run_tests/artifacts/distribtest_targets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index 1e58b2c19fa..b611a1560a8 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -361,14 +361,14 @@ class CppDistribTest(object): "tools/dockerfile/distribtest/cpp_%s_%s" % (self.docker_suffix, self.arch), "test/distrib/cpp/run_distrib_test_%s.sh" % self.testcase, - timeout_seconds=45 * 60, + timeout_seconds=60 * 60, ) elif self.platform == "windows": return create_jobspec( self.name, ["test\\distrib\\cpp\\run_distrib_test_%s.bat" % self.testcase], environ={}, - timeout_seconds=45 * 60, + timeout_seconds=60 * 60, use_workspace=True, ) else: From 6cfa2e9edb145f8de5fee42243f40bfdd8878be3 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Jan 2024 12:12:43 -0800 Subject: [PATCH 22/27] [chaotic-good] Disable cmake tests - these are not interesting (#35486) Closes #35486 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35486 from ctiller:phooey 310a5cc762404ae899ffca17f258f390f3919c88 PiperOrigin-RevId: 597007485 --- CMakeLists.txt | 517 +----------- build_autogenerated.yaml | 798 +----------------- .../extract_metadata_from_bazel_xml.py | 7 + tools/run_tests/generated/tests.json | 124 +-- 4 files changed, 42 insertions(+), 1404 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1dbc6db5e0e..3d544e34f75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -959,8 +959,6 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_cxx client_ssl_test) endif() add_dependencies(buildtests_cxx client_streaming_test) - add_dependencies(buildtests_cxx client_transport_error_test) - add_dependencies(buildtests_cxx client_transport_test) add_dependencies(buildtests_cxx cmdline_test) add_dependencies(buildtests_cxx codegen_test_full) add_dependencies(buildtests_cxx codegen_test_minimal) @@ -1045,7 +1043,7 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_cxx forkable_test) add_dependencies(buildtests_cxx format_request_test) add_dependencies(buildtests_cxx frame_handler_test) - add_dependencies(buildtests_cxx frame_header_test) + add_dependencies(buildtests_cxx frame_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx fuzzing_event_engine_test) endif() @@ -1327,7 +1325,6 @@ if(gRPC_BUILD_TESTS) endif() add_dependencies(buildtests_cxx server_streaming_test) add_dependencies(buildtests_cxx server_test) - add_dependencies(buildtests_cxx server_transport_test) add_dependencies(buildtests_cxx service_config_end2end_test) add_dependencies(buildtests_cxx service_config_test) add_dependencies(buildtests_cxx settings_timeout_test) @@ -1404,8 +1401,6 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_cxx test_core_security_ssl_credentials_test) add_dependencies(buildtests_cxx test_core_slice_slice_buffer_test) add_dependencies(buildtests_cxx test_core_slice_slice_test) - add_dependencies(buildtests_cxx test_core_transport_chaotic_good_frame_test) - add_dependencies(buildtests_cxx test_core_transport_chttp2_frame_test) add_dependencies(buildtests_cxx test_cpp_client_credentials_test) add_dependencies(buildtests_cxx test_cpp_end2end_ssl_credentials_test) add_dependencies(buildtests_cxx test_cpp_server_credentials_test) @@ -9579,97 +9574,6 @@ target_link_libraries(client_streaming_test ) -endif() -if(gRPC_BUILD_TESTS) - -add_executable(client_transport_error_test - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.cc - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - src/core/ext/transport/chaotic_good/client_transport.cc - src/core/ext/transport/chaotic_good/frame.cc - src/core/ext/transport/chaotic_good/frame_header.cc - src/core/lib/transport/promise_endpoint.cc - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - test/core/transport/chaotic_good/client_transport_error_test.cc -) -target_compile_features(client_transport_error_test PUBLIC cxx_std_14) -target_include_directories(client_transport_error_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(client_transport_error_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gtest - grpc_unsecure - ${_gRPC_PROTOBUF_LIBRARIES} - grpc_test_util -) - - -endif() -if(gRPC_BUILD_TESTS) - -add_executable(client_transport_test - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.cc - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - src/core/ext/transport/chaotic_good/client_transport.cc - src/core/ext/transport/chaotic_good/frame.cc - src/core/ext/transport/chaotic_good/frame_header.cc - src/core/lib/transport/promise_endpoint.cc - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - test/core/transport/chaotic_good/client_transport_test.cc - test/core/transport/chaotic_good/mock_promise_endpoint.cc - test/core/transport/chaotic_good/transport_test.cc -) -target_compile_features(client_transport_test PUBLIC cxx_std_14) -target_include_directories(client_transport_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(client_transport_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gtest - ${_gRPC_PROTOBUF_LIBRARIES} - grpc_test_util -) - - endif() if(gRPC_BUILD_TESTS) @@ -12579,12 +12483,17 @@ target_link_libraries(frame_handler_test endif() if(gRPC_BUILD_TESTS) -add_executable(frame_header_test - src/core/ext/transport/chaotic_good/frame_header.cc - test/core/transport/chaotic_good/frame_header_test.cc +add_executable(frame_test + src/core/ext/transport/chttp2/transport/frame.cc + src/core/lib/debug/trace.cc + src/core/lib/slice/slice.cc + src/core/lib/slice/slice_buffer.cc + src/core/lib/slice/slice_refcount.cc + src/core/lib/slice/slice_string_helpers.cc + test/core/transport/chttp2/frame_test.cc ) -target_compile_features(frame_header_test PUBLIC cxx_std_14) -target_include_directories(frame_header_test +target_compile_features(frame_test PUBLIC cxx_std_14) +target_include_directories(frame_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -12603,10 +12512,12 @@ target_include_directories(frame_header_test ${_gRPC_PROTO_GENS_DIR} ) -target_link_libraries(frame_header_test +target_link_libraries(frame_test ${_gRPC_ALLTARGETS_LIBRARIES} gtest + absl::hash absl::statusor + absl::span gpr ) @@ -22439,52 +22350,6 @@ target_link_libraries(server_test ) -endif() -if(gRPC_BUILD_TESTS) - -add_executable(server_transport_test - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.cc - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h - ${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - src/core/ext/transport/chaotic_good/frame.cc - src/core/ext/transport/chaotic_good/frame_header.cc - src/core/ext/transport/chaotic_good/server_transport.cc - src/core/lib/transport/promise_endpoint.cc - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - test/core/transport/chaotic_good/mock_promise_endpoint.cc - test/core/transport/chaotic_good/server_transport_test.cc - test/core/transport/chaotic_good/transport_test.cc -) -target_compile_features(server_transport_test PUBLIC cxx_std_14) -target_include_directories(server_transport_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(server_transport_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gtest - ${_gRPC_PROTOBUF_LIBRARIES} - grpc_test_util -) - - endif() if(gRPC_BUILD_TESTS) @@ -24724,360 +24589,6 @@ target_link_libraries(test_core_slice_slice_test ) -endif() -if(gRPC_BUILD_TESTS) - -add_executable(test_core_transport_chaotic_good_frame_test - src/core/ext/transport/chaotic_good/frame.cc - src/core/ext/transport/chaotic_good/frame_header.cc - src/core/ext/transport/chttp2/transport/bin_encoder.cc - src/core/ext/transport/chttp2/transport/decode_huff.cc - src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc - src/core/ext/transport/chttp2/transport/hpack_parse_result.cc - src/core/ext/transport/chttp2/transport/hpack_parser.cc - src/core/ext/transport/chttp2/transport/hpack_parser_table.cc - src/core/ext/transport/chttp2/transport/http_trace.cc - src/core/ext/transport/chttp2/transport/huffsyms.cc - src/core/ext/transport/chttp2/transport/varint.cc - src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c - src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c - src/core/ext/upb-gen/google/rpc/status.upb_minitable.c - src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c - src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c - src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c - src/core/lib/address_utils/parse_address.cc - src/core/lib/address_utils/sockaddr_utils.cc - src/core/lib/backoff/backoff.cc - src/core/lib/backoff/random_early_detection.cc - src/core/lib/channel/call_tracer.cc - src/core/lib/channel/channel_args.cc - src/core/lib/channel/channel_args_preconditioning.cc - src/core/lib/channel/channel_stack.cc - src/core/lib/channel/channel_stack_builder.cc - src/core/lib/channel/channel_stack_builder_impl.cc - src/core/lib/channel/channel_stack_trace.cc - src/core/lib/channel/channel_trace.cc - src/core/lib/channel/channelz.cc - src/core/lib/channel/channelz_registry.cc - src/core/lib/channel/connected_channel.cc - src/core/lib/channel/promise_based_filter.cc - src/core/lib/channel/server_call_tracer_filter.cc - src/core/lib/channel/status_util.cc - src/core/lib/compression/compression.cc - src/core/lib/compression/compression_internal.cc - src/core/lib/compression/message_compress.cc - src/core/lib/config/core_configuration.cc - src/core/lib/debug/event_log.cc - src/core/lib/debug/histogram_view.cc - src/core/lib/debug/stats.cc - src/core/lib/debug/stats_data.cc - src/core/lib/debug/trace.cc - src/core/lib/event_engine/ares_resolver.cc - src/core/lib/event_engine/cf_engine/cf_engine.cc - src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc - src/core/lib/event_engine/cf_engine/dns_service_resolver.cc - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/default_event_engine.cc - src/core/lib/event_engine/default_event_engine_factory.cc - src/core/lib/event_engine/event_engine.cc - src/core/lib/event_engine/forkable.cc - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc - src/core/lib/event_engine/posix_engine/ev_poll_posix.cc - src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc - src/core/lib/event_engine/posix_engine/internal_errqueue.cc - src/core/lib/event_engine/posix_engine/lockfree_event.cc - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc - src/core/lib/event_engine/posix_engine/posix_endpoint.cc - src/core/lib/event_engine/posix_engine/posix_engine.cc - src/core/lib/event_engine/posix_engine/posix_engine_listener.cc - src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc - src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc - src/core/lib/event_engine/posix_engine/timer.cc - src/core/lib/event_engine/posix_engine/timer_heap.cc - src/core/lib/event_engine/posix_engine/timer_manager.cc - src/core/lib/event_engine/posix_engine/traced_buffer_list.cc - src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc - src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc - src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc - src/core/lib/event_engine/resolved_address.cc - src/core/lib/event_engine/shim.cc - src/core/lib/event_engine/slice.cc - src/core/lib/event_engine/slice_buffer.cc - src/core/lib/event_engine/tcp_socket_utils.cc - src/core/lib/event_engine/thread_pool/thread_count.cc - src/core/lib/event_engine/thread_pool/thread_pool_factory.cc - src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc - src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc - src/core/lib/event_engine/time_util.cc - src/core/lib/event_engine/trace.cc - src/core/lib/event_engine/utils.cc - src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc - src/core/lib/event_engine/windows/iocp.cc - src/core/lib/event_engine/windows/native_windows_dns_resolver.cc - src/core/lib/event_engine/windows/win_socket.cc - src/core/lib/event_engine/windows/windows_endpoint.cc - src/core/lib/event_engine/windows/windows_engine.cc - src/core/lib/event_engine/windows/windows_listener.cc - src/core/lib/event_engine/work_queue/basic_work_queue.cc - src/core/lib/experiments/config.cc - src/core/lib/experiments/experiments.cc - src/core/lib/gprpp/load_file.cc - src/core/lib/gprpp/per_cpu.cc - src/core/lib/gprpp/ref_counted_string.cc - src/core/lib/gprpp/status_helper.cc - src/core/lib/gprpp/time.cc - src/core/lib/gprpp/time_averaged_stats.cc - src/core/lib/gprpp/validation_errors.cc - src/core/lib/gprpp/work_serializer.cc - src/core/lib/handshaker/proxy_mapper_registry.cc - src/core/lib/iomgr/buffer_list.cc - src/core/lib/iomgr/call_combiner.cc - src/core/lib/iomgr/cfstream_handle.cc - src/core/lib/iomgr/closure.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/dualstack_socket_posix.cc - src/core/lib/iomgr/endpoint.cc - src/core/lib/iomgr/endpoint_cfstream.cc - src/core/lib/iomgr/endpoint_pair_posix.cc - src/core/lib/iomgr/endpoint_pair_windows.cc - src/core/lib/iomgr/error.cc - src/core/lib/iomgr/error_cfstream.cc - src/core/lib/iomgr/ev_apple.cc - src/core/lib/iomgr/ev_epoll1_linux.cc - src/core/lib/iomgr/ev_poll_posix.cc - src/core/lib/iomgr/ev_posix.cc - src/core/lib/iomgr/ev_windows.cc - src/core/lib/iomgr/event_engine_shims/closure.cc - src/core/lib/iomgr/event_engine_shims/endpoint.cc - src/core/lib/iomgr/event_engine_shims/tcp_client.cc - src/core/lib/iomgr/exec_ctx.cc - src/core/lib/iomgr/executor.cc - src/core/lib/iomgr/fork_posix.cc - src/core/lib/iomgr/fork_windows.cc - src/core/lib/iomgr/gethostname_fallback.cc - src/core/lib/iomgr/gethostname_host_name_max.cc - src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/grpc_if_nametoindex_posix.cc - src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc - src/core/lib/iomgr/internal_errqueue.cc - src/core/lib/iomgr/iocp_windows.cc - src/core/lib/iomgr/iomgr.cc - src/core/lib/iomgr/iomgr_internal.cc - src/core/lib/iomgr/iomgr_posix.cc - src/core/lib/iomgr/iomgr_posix_cfstream.cc - src/core/lib/iomgr/iomgr_windows.cc - src/core/lib/iomgr/load_file.cc - src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/polling_entity.cc - src/core/lib/iomgr/pollset.cc - src/core/lib/iomgr/pollset_set.cc - src/core/lib/iomgr/pollset_set_windows.cc - src/core/lib/iomgr/pollset_windows.cc - src/core/lib/iomgr/resolve_address.cc - src/core/lib/iomgr/resolve_address_posix.cc - src/core/lib/iomgr/resolve_address_windows.cc - src/core/lib/iomgr/sockaddr_utils_posix.cc - src/core/lib/iomgr/socket_factory_posix.cc - src/core/lib/iomgr/socket_mutator.cc - src/core/lib/iomgr/socket_utils_common_posix.cc - src/core/lib/iomgr/socket_utils_linux.cc - src/core/lib/iomgr/socket_utils_posix.cc - src/core/lib/iomgr/socket_utils_windows.cc - src/core/lib/iomgr/socket_windows.cc - src/core/lib/iomgr/systemd_utils.cc - src/core/lib/iomgr/tcp_client.cc - src/core/lib/iomgr/tcp_client_cfstream.cc - src/core/lib/iomgr/tcp_client_posix.cc - src/core/lib/iomgr/tcp_client_windows.cc - src/core/lib/iomgr/tcp_posix.cc - src/core/lib/iomgr/tcp_server.cc - src/core/lib/iomgr/tcp_server_posix.cc - src/core/lib/iomgr/tcp_server_utils_posix_common.cc - src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc - src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc - src/core/lib/iomgr/tcp_server_windows.cc - src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/timer.cc - src/core/lib/iomgr/timer_generic.cc - src/core/lib/iomgr/timer_heap.cc - src/core/lib/iomgr/timer_manager.cc - src/core/lib/iomgr/unix_sockets_posix.cc - src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/vsock.cc - src/core/lib/iomgr/wakeup_fd_eventfd.cc - src/core/lib/iomgr/wakeup_fd_nospecial.cc - src/core/lib/iomgr/wakeup_fd_pipe.cc - src/core/lib/iomgr/wakeup_fd_posix.cc - src/core/lib/json/json_writer.cc - src/core/lib/load_balancing/lb_policy.cc - src/core/lib/load_balancing/lb_policy_registry.cc - src/core/lib/promise/activity.cc - src/core/lib/promise/party.cc - src/core/lib/promise/trace.cc - src/core/lib/resolver/endpoint_addresses.cc - src/core/lib/resolver/resolver.cc - src/core/lib/resolver/resolver_registry.cc - src/core/lib/resource_quota/api.cc - src/core/lib/resource_quota/arena.cc - src/core/lib/resource_quota/memory_quota.cc - src/core/lib/resource_quota/periodic_update.cc - src/core/lib/resource_quota/resource_quota.cc - src/core/lib/resource_quota/thread_quota.cc - src/core/lib/resource_quota/trace.cc - src/core/lib/security/certificate_provider/certificate_provider_registry.cc - src/core/lib/security/credentials/alts/check_gcp_environment.cc - src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc - src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc - src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc - src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc - src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc - src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc - src/core/lib/service_config/service_config_parser.cc - src/core/lib/slice/b64.cc - src/core/lib/slice/percent_encoding.cc - src/core/lib/slice/slice.cc - src/core/lib/slice/slice_buffer.cc - src/core/lib/slice/slice_refcount.cc - src/core/lib/slice/slice_string_helpers.cc - src/core/lib/surface/api_trace.cc - src/core/lib/surface/builtins.cc - src/core/lib/surface/byte_buffer.cc - src/core/lib/surface/byte_buffer_reader.cc - src/core/lib/surface/call.cc - src/core/lib/surface/call_details.cc - src/core/lib/surface/call_log_batch.cc - src/core/lib/surface/call_trace.cc - src/core/lib/surface/channel.cc - src/core/lib/surface/channel_init.cc - src/core/lib/surface/channel_ping.cc - src/core/lib/surface/channel_stack_type.cc - src/core/lib/surface/completion_queue.cc - src/core/lib/surface/completion_queue_factory.cc - src/core/lib/surface/event_string.cc - src/core/lib/surface/init_internally.cc - src/core/lib/surface/lame_client.cc - src/core/lib/surface/metadata_array.cc - src/core/lib/surface/server.cc - src/core/lib/surface/validate_metadata.cc - src/core/lib/surface/version.cc - src/core/lib/transport/batch_builder.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc - src/core/lib/transport/handshaker_registry.cc - src/core/lib/transport/metadata_batch.cc - src/core/lib/transport/parsed_metadata.cc - src/core/lib/transport/status_conversion.cc - src/core/lib/transport/timeout_encoding.cc - src/core/lib/transport/transport.cc - src/core/lib/transport/transport_op_string.cc - src/core/lib/uri/uri_parser.cc - src/core/tsi/alts/handshaker/transport_security_common_api.cc - test/core/transport/chaotic_good/frame_test.cc - third_party/upb/upb/hash/common.c - third_party/upb/upb/message/accessors.c - third_party/upb/upb/message/array.c - third_party/upb/upb/message/map.c - third_party/upb/upb/message/map_sorter.c - third_party/upb/upb/message/message.c - third_party/upb/upb/mini_descriptor/build_enum.c - third_party/upb/upb/mini_descriptor/decode.c - third_party/upb/upb/mini_descriptor/internal/base92.c - third_party/upb/upb/mini_descriptor/internal/encode.c - third_party/upb/upb/mini_descriptor/link.c - third_party/upb/upb/mini_table/extension_registry.c - third_party/upb/upb/mini_table/internal/message.c - third_party/upb/upb/mini_table/message.c - third_party/upb/upb/wire/decode.c - third_party/upb/upb/wire/decode_fast.c - third_party/upb/upb/wire/encode.c - third_party/upb/upb/wire/eps_copy_input_stream.c - third_party/upb/upb/wire/reader.c -) -target_compile_features(test_core_transport_chaotic_good_frame_test PUBLIC cxx_std_14) -target_include_directories(test_core_transport_chaotic_good_frame_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(test_core_transport_chaotic_good_frame_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gtest - upb - utf8_range_lib - ${_gRPC_ZLIB_LIBRARIES} - absl::cleanup - absl::flat_hash_map - absl::inlined_vector - absl::function_ref - absl::hash - absl::type_traits - absl::random_bit_gen_ref - absl::random_distributions - absl::statusor - absl::span - absl::utility - ${_gRPC_CARES_LIBRARIES} - gpr -) - - -endif() -if(gRPC_BUILD_TESTS) - -add_executable(test_core_transport_chttp2_frame_test - src/core/ext/transport/chttp2/transport/frame.cc - src/core/lib/debug/trace.cc - src/core/lib/slice/slice.cc - src/core/lib/slice/slice_buffer.cc - src/core/lib/slice/slice_refcount.cc - src/core/lib/slice/slice_string_helpers.cc - test/core/transport/chttp2/frame_test.cc -) -target_compile_features(test_core_transport_chttp2_frame_test PUBLIC cxx_std_14) -target_include_directories(test_core_transport_chttp2_frame_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(test_core_transport_chttp2_frame_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gtest - absl::hash - absl::statusor - absl::span - gpr -) - - endif() if(gRPC_BUILD_TESTS) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 9f9385d801d..4eecb357b2f 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -7665,70 +7665,6 @@ targets: - grpc_authorization_provider - grpc_unsecure - grpc_test_util -- name: client_transport_error_test - gtest: true - build: test - language: c++ - headers: - - src/core/ext/transport/chaotic_good/chaotic_good_transport.h - - src/core/ext/transport/chaotic_good/client_transport.h - - src/core/ext/transport/chaotic_good/frame.h - - src/core/ext/transport/chaotic_good/frame_header.h - - src/core/lib/promise/event_engine_wakeup_scheduler.h - - src/core/lib/promise/inter_activity_pipe.h - - src/core/lib/promise/join.h - - src/core/lib/promise/mpsc.h - - src/core/lib/promise/wait_set.h - - src/core/lib/transport/promise_endpoint.h - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h - src: - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto - - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - - src/core/ext/transport/chaotic_good/client_transport.cc - - src/core/ext/transport/chaotic_good/frame.cc - - src/core/ext/transport/chaotic_good/frame_header.cc - - src/core/lib/transport/promise_endpoint.cc - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - - test/core/transport/chaotic_good/client_transport_error_test.cc - deps: - - gtest - - grpc_unsecure - - protobuf - - grpc_test_util - uses_polling: false -- name: client_transport_test - gtest: true - build: test - language: c++ - headers: - - src/core/ext/transport/chaotic_good/chaotic_good_transport.h - - src/core/ext/transport/chaotic_good/client_transport.h - - src/core/ext/transport/chaotic_good/frame.h - - src/core/ext/transport/chaotic_good/frame_header.h - - src/core/lib/promise/event_engine_wakeup_scheduler.h - - src/core/lib/promise/inter_activity_pipe.h - - src/core/lib/promise/mpsc.h - - src/core/lib/promise/wait_set.h - - src/core/lib/transport/promise_endpoint.h - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h - - test/core/transport/chaotic_good/mock_promise_endpoint.h - - test/core/transport/chaotic_good/transport_test.h - src: - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto - - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - - src/core/ext/transport/chaotic_good/client_transport.cc - - src/core/ext/transport/chaotic_good/frame.cc - - src/core/ext/transport/chaotic_good/frame_header.cc - - src/core/lib/transport/promise_endpoint.cc - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - - test/core/transport/chaotic_good/client_transport_test.cc - - test/core/transport/chaotic_good/mock_promise_endpoint.cc - - test/core/transport/chaotic_good/transport_test.cc - deps: - - gtest - - protobuf - - grpc_test_util - uses_polling: false - name: cmdline_test gtest: true build: test @@ -9674,20 +9610,34 @@ targets: deps: - gtest - grpc_test_util -- name: frame_header_test +- name: frame_test gtest: true build: test language: c++ headers: - - src/core/ext/transport/chaotic_good/frame_header.h - - src/core/lib/gprpp/bitset.h + - src/core/ext/transport/chttp2/transport/frame.h + - src/core/lib/debug/trace.h + - src/core/lib/slice/slice.h + - src/core/lib/slice/slice_buffer.h + - src/core/lib/slice/slice_internal.h + - src/core/lib/slice/slice_refcount.h + - src/core/lib/slice/slice_string_helpers.h + - src/core/lib/transport/http2_errors.h src: - - src/core/ext/transport/chaotic_good/frame_header.cc - - test/core/transport/chaotic_good/frame_header_test.cc + - src/core/ext/transport/chttp2/transport/frame.cc + - src/core/lib/debug/trace.cc + - src/core/lib/slice/slice.cc + - src/core/lib/slice/slice_buffer.cc + - src/core/lib/slice/slice_refcount.cc + - src/core/lib/slice/slice_string_helpers.cc + - test/core/transport/chttp2/frame_test.cc deps: - gtest + - absl/hash:hash - absl/status:statusor + - absl/types:span - gpr + uses_polling: false - name: fuzzing_event_engine_test gtest: true build: test @@ -15600,40 +15550,6 @@ targets: deps: - gtest - grpc_test_util -- name: server_transport_test - gtest: true - build: test - language: c++ - headers: - - src/core/ext/transport/chaotic_good/chaotic_good_transport.h - - src/core/ext/transport/chaotic_good/frame.h - - src/core/ext/transport/chaotic_good/frame_header.h - - src/core/ext/transport/chaotic_good/server_transport.h - - src/core/lib/promise/event_engine_wakeup_scheduler.h - - src/core/lib/promise/inter_activity_pipe.h - - src/core/lib/promise/mpsc.h - - src/core/lib/promise/switch.h - - src/core/lib/promise/wait_set.h - - src/core/lib/transport/promise_endpoint.h - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h - - test/core/transport/chaotic_good/mock_promise_endpoint.h - - test/core/transport/chaotic_good/transport_test.h - src: - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto - - src/core/ext/transport/chaotic_good/chaotic_good_transport.cc - - src/core/ext/transport/chaotic_good/frame.cc - - src/core/ext/transport/chaotic_good/frame_header.cc - - src/core/ext/transport/chaotic_good/server_transport.cc - - src/core/lib/transport/promise_endpoint.cc - - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc - - test/core/transport/chaotic_good/mock_promise_endpoint.cc - - test/core/transport/chaotic_good/server_transport_test.cc - - test/core/transport/chaotic_good/transport_test.cc - deps: - - gtest - - protobuf - - grpc_test_util - uses_polling: false - name: service_config_end2end_test gtest: true build: test @@ -16836,682 +16752,6 @@ targets: - gtest - grpc uses_polling: false -- name: test_core_transport_chaotic_good_frame_test - gtest: true - build: test - language: c++ - headers: - - src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h - - src/core/ext/transport/chaotic_good/frame.h - - src/core/ext/transport/chaotic_good/frame_header.h - - src/core/ext/transport/chttp2/transport/bin_encoder.h - - src/core/ext/transport/chttp2/transport/decode_huff.h - - src/core/ext/transport/chttp2/transport/hpack_constants.h - - src/core/ext/transport/chttp2/transport/hpack_encoder.h - - src/core/ext/transport/chttp2/transport/hpack_encoder_table.h - - src/core/ext/transport/chttp2/transport/hpack_parse_result.h - - src/core/ext/transport/chttp2/transport/hpack_parser.h - - src/core/ext/transport/chttp2/transport/hpack_parser_table.h - - src/core/ext/transport/chttp2/transport/http_trace.h - - src/core/ext/transport/chttp2/transport/huffsyms.h - - src/core/ext/transport/chttp2/transport/legacy_frame.h - - src/core/ext/transport/chttp2/transport/varint.h - - src/core/ext/upb-gen/google/protobuf/any.upb.h - - src/core/ext/upb-gen/google/protobuf/any.upb_minitable.h - - src/core/ext/upb-gen/google/protobuf/descriptor.upb.h - - src/core/ext/upb-gen/google/rpc/status.upb.h - - src/core/ext/upb-gen/google/rpc/status.upb_minitable.h - - src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb.h - - src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.h - - src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb.h - - src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.h - - src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb.h - - src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.h - - src/core/lib/address_utils/parse_address.h - - src/core/lib/address_utils/sockaddr_utils.h - - src/core/lib/avl/avl.h - - src/core/lib/backoff/backoff.h - - src/core/lib/backoff/random_early_detection.h - - src/core/lib/channel/call_finalization.h - - src/core/lib/channel/call_tracer.h - - src/core/lib/channel/channel_args.h - - src/core/lib/channel/channel_args_preconditioning.h - - src/core/lib/channel/channel_fwd.h - - src/core/lib/channel/channel_stack.h - - src/core/lib/channel/channel_stack_builder.h - - src/core/lib/channel/channel_stack_builder_impl.h - - src/core/lib/channel/channel_stack_trace.h - - src/core/lib/channel/channel_trace.h - - src/core/lib/channel/channelz.h - - src/core/lib/channel/channelz_registry.h - - src/core/lib/channel/connected_channel.h - - src/core/lib/channel/context.h - - src/core/lib/channel/promise_based_filter.h - - src/core/lib/channel/status_util.h - - src/core/lib/channel/tcp_tracer.h - - src/core/lib/compression/compression_internal.h - - src/core/lib/compression/message_compress.h - - src/core/lib/config/core_configuration.h - - src/core/lib/debug/event_log.h - - src/core/lib/debug/histogram_view.h - - src/core/lib/debug/stats.h - - src/core/lib/debug/stats_data.h - - src/core/lib/debug/trace.h - - src/core/lib/event_engine/ares_resolver.h - - src/core/lib/event_engine/cf_engine/cf_engine.h - - src/core/lib/event_engine/cf_engine/cfstream_endpoint.h - - src/core/lib/event_engine/cf_engine/cftype_unique_ref.h - - src/core/lib/event_engine/cf_engine/dns_service_resolver.h - - src/core/lib/event_engine/channel_args_endpoint_config.h - - src/core/lib/event_engine/common_closures.h - - src/core/lib/event_engine/default_event_engine.h - - src/core/lib/event_engine/default_event_engine_factory.h - - src/core/lib/event_engine/forkable.h - - src/core/lib/event_engine/grpc_polled_fd.h - - src/core/lib/event_engine/handle_containers.h - - src/core/lib/event_engine/memory_allocator_factory.h - - src/core/lib/event_engine/nameser.h - - src/core/lib/event_engine/poller.h - - src/core/lib/event_engine/posix.h - - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h - - src/core/lib/event_engine/posix_engine/ev_poll_posix.h - - src/core/lib/event_engine/posix_engine/event_poller.h - - src/core/lib/event_engine/posix_engine/event_poller_posix_default.h - - src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h - - src/core/lib/event_engine/posix_engine/internal_errqueue.h - - src/core/lib/event_engine/posix_engine/lockfree_event.h - - src/core/lib/event_engine/posix_engine/native_dns_resolver.h - - src/core/lib/event_engine/posix_engine/posix_endpoint.h - - src/core/lib/event_engine/posix_engine/posix_engine.h - - src/core/lib/event_engine/posix_engine/posix_engine_closure.h - - src/core/lib/event_engine/posix_engine/posix_engine_listener.h - - src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h - - src/core/lib/event_engine/posix_engine/tcp_socket_utils.h - - src/core/lib/event_engine/posix_engine/timer.h - - src/core/lib/event_engine/posix_engine/timer_heap.h - - src/core/lib/event_engine/posix_engine/timer_manager.h - - src/core/lib/event_engine/posix_engine/traced_buffer_list.h - - src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h - - src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h - - src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h - - src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h - - src/core/lib/event_engine/ref_counted_dns_resolver_interface.h - - src/core/lib/event_engine/resolved_address_internal.h - - src/core/lib/event_engine/shim.h - - src/core/lib/event_engine/tcp_socket_utils.h - - src/core/lib/event_engine/thread_pool/thread_count.h - - src/core/lib/event_engine/thread_pool/thread_pool.h - - src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h - - src/core/lib/event_engine/thready_event_engine/thready_event_engine.h - - src/core/lib/event_engine/time_util.h - - src/core/lib/event_engine/trace.h - - src/core/lib/event_engine/utils.h - - src/core/lib/event_engine/windows/grpc_polled_fd_windows.h - - src/core/lib/event_engine/windows/iocp.h - - src/core/lib/event_engine/windows/native_windows_dns_resolver.h - - src/core/lib/event_engine/windows/win_socket.h - - src/core/lib/event_engine/windows/windows_endpoint.h - - src/core/lib/event_engine/windows/windows_engine.h - - src/core/lib/event_engine/windows/windows_listener.h - - src/core/lib/event_engine/work_queue/basic_work_queue.h - - src/core/lib/event_engine/work_queue/work_queue.h - - src/core/lib/experiments/config.h - - src/core/lib/experiments/experiments.h - - src/core/lib/gpr/spinlock.h - - src/core/lib/gprpp/atomic_utils.h - - src/core/lib/gprpp/bitset.h - - src/core/lib/gprpp/chunked_vector.h - - src/core/lib/gprpp/cpp_impl_of.h - - src/core/lib/gprpp/dual_ref_counted.h - - src/core/lib/gprpp/if_list.h - - src/core/lib/gprpp/load_file.h - - src/core/lib/gprpp/manual_constructor.h - - src/core/lib/gprpp/match.h - - src/core/lib/gprpp/notification.h - - src/core/lib/gprpp/orphanable.h - - src/core/lib/gprpp/overload.h - - src/core/lib/gprpp/packed_table.h - - src/core/lib/gprpp/per_cpu.h - - src/core/lib/gprpp/ref_counted.h - - src/core/lib/gprpp/ref_counted_ptr.h - - src/core/lib/gprpp/ref_counted_string.h - - src/core/lib/gprpp/sorted_pack.h - - src/core/lib/gprpp/status_helper.h - - src/core/lib/gprpp/table.h - - src/core/lib/gprpp/time.h - - src/core/lib/gprpp/time_averaged_stats.h - - src/core/lib/gprpp/type_list.h - - src/core/lib/gprpp/unique_type_name.h - - src/core/lib/gprpp/validation_errors.h - - src/core/lib/gprpp/work_serializer.h - - src/core/lib/handshaker/proxy_mapper.h - - src/core/lib/handshaker/proxy_mapper_registry.h - - src/core/lib/iomgr/block_annotate.h - - src/core/lib/iomgr/buffer_list.h - - src/core/lib/iomgr/call_combiner.h - - src/core/lib/iomgr/cfstream_handle.h - - src/core/lib/iomgr/closure.h - - src/core/lib/iomgr/combiner.h - - src/core/lib/iomgr/dynamic_annotations.h - - src/core/lib/iomgr/endpoint.h - - src/core/lib/iomgr/endpoint_cfstream.h - - src/core/lib/iomgr/endpoint_pair.h - - src/core/lib/iomgr/error.h - - src/core/lib/iomgr/error_cfstream.h - - src/core/lib/iomgr/ev_apple.h - - src/core/lib/iomgr/ev_epoll1_linux.h - - src/core/lib/iomgr/ev_poll_posix.h - - src/core/lib/iomgr/ev_posix.h - - src/core/lib/iomgr/event_engine_shims/closure.h - - src/core/lib/iomgr/event_engine_shims/endpoint.h - - src/core/lib/iomgr/event_engine_shims/tcp_client.h - - src/core/lib/iomgr/exec_ctx.h - - src/core/lib/iomgr/executor.h - - src/core/lib/iomgr/gethostname.h - - src/core/lib/iomgr/grpc_if_nametoindex.h - - src/core/lib/iomgr/internal_errqueue.h - - src/core/lib/iomgr/iocp_windows.h - - src/core/lib/iomgr/iomgr.h - - src/core/lib/iomgr/iomgr_fwd.h - - src/core/lib/iomgr/iomgr_internal.h - - src/core/lib/iomgr/load_file.h - - src/core/lib/iomgr/lockfree_event.h - - src/core/lib/iomgr/nameser.h - - src/core/lib/iomgr/polling_entity.h - - src/core/lib/iomgr/pollset.h - - src/core/lib/iomgr/pollset_set.h - - src/core/lib/iomgr/pollset_set_windows.h - - src/core/lib/iomgr/pollset_windows.h - - src/core/lib/iomgr/port.h - - src/core/lib/iomgr/python_util.h - - src/core/lib/iomgr/resolve_address.h - - src/core/lib/iomgr/resolve_address_impl.h - - src/core/lib/iomgr/resolve_address_posix.h - - src/core/lib/iomgr/resolve_address_windows.h - - src/core/lib/iomgr/resolved_address.h - - src/core/lib/iomgr/sockaddr.h - - src/core/lib/iomgr/sockaddr_posix.h - - src/core/lib/iomgr/sockaddr_windows.h - - src/core/lib/iomgr/socket_factory_posix.h - - src/core/lib/iomgr/socket_mutator.h - - src/core/lib/iomgr/socket_utils.h - - src/core/lib/iomgr/socket_utils_posix.h - - src/core/lib/iomgr/socket_windows.h - - src/core/lib/iomgr/systemd_utils.h - - src/core/lib/iomgr/tcp_client.h - - src/core/lib/iomgr/tcp_client_posix.h - - src/core/lib/iomgr/tcp_posix.h - - src/core/lib/iomgr/tcp_server.h - - src/core/lib/iomgr/tcp_server_utils_posix.h - - src/core/lib/iomgr/tcp_windows.h - - src/core/lib/iomgr/timer.h - - src/core/lib/iomgr/timer_generic.h - - src/core/lib/iomgr/timer_heap.h - - src/core/lib/iomgr/timer_manager.h - - src/core/lib/iomgr/unix_sockets_posix.h - - src/core/lib/iomgr/vsock.h - - src/core/lib/iomgr/wakeup_fd_pipe.h - - src/core/lib/iomgr/wakeup_fd_posix.h - - src/core/lib/json/json.h - - src/core/lib/json/json_args.h - - src/core/lib/json/json_writer.h - - src/core/lib/load_balancing/lb_policy.h - - src/core/lib/load_balancing/lb_policy_factory.h - - src/core/lib/load_balancing/lb_policy_registry.h - - src/core/lib/load_balancing/subchannel_interface.h - - src/core/lib/promise/activity.h - - src/core/lib/promise/all_ok.h - - src/core/lib/promise/arena_promise.h - - src/core/lib/promise/cancel_callback.h - - src/core/lib/promise/context.h - - src/core/lib/promise/detail/basic_seq.h - - src/core/lib/promise/detail/join_state.h - - src/core/lib/promise/detail/promise_factory.h - - src/core/lib/promise/detail/promise_like.h - - src/core/lib/promise/detail/seq_state.h - - src/core/lib/promise/detail/status.h - - src/core/lib/promise/exec_ctx_wakeup_scheduler.h - - src/core/lib/promise/for_each.h - - src/core/lib/promise/if.h - - src/core/lib/promise/interceptor_list.h - - src/core/lib/promise/latch.h - - src/core/lib/promise/loop.h - - src/core/lib/promise/map.h - - src/core/lib/promise/party.h - - src/core/lib/promise/pipe.h - - src/core/lib/promise/poll.h - - src/core/lib/promise/promise.h - - src/core/lib/promise/race.h - - src/core/lib/promise/seq.h - - src/core/lib/promise/status_flag.h - - src/core/lib/promise/trace.h - - src/core/lib/promise/try_join.h - - src/core/lib/promise/try_seq.h - - src/core/lib/resolver/endpoint_addresses.h - - src/core/lib/resolver/resolver.h - - src/core/lib/resolver/resolver_factory.h - - src/core/lib/resolver/resolver_registry.h - - src/core/lib/resolver/server_address.h - - src/core/lib/resource_quota/api.h - - src/core/lib/resource_quota/arena.h - - src/core/lib/resource_quota/memory_quota.h - - src/core/lib/resource_quota/periodic_update.h - - src/core/lib/resource_quota/resource_quota.h - - src/core/lib/resource_quota/thread_quota.h - - src/core/lib/resource_quota/trace.h - - src/core/lib/security/certificate_provider/certificate_provider_factory.h - - src/core/lib/security/certificate_provider/certificate_provider_registry.h - - src/core/lib/security/credentials/alts/check_gcp_environment.h - - src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h - - src/core/lib/security/credentials/channel_creds_registry.h - - src/core/lib/service_config/service_config.h - - src/core/lib/service_config/service_config_call_data.h - - src/core/lib/service_config/service_config_parser.h - - src/core/lib/slice/b64.h - - src/core/lib/slice/percent_encoding.h - - src/core/lib/slice/slice.h - - src/core/lib/slice/slice_buffer.h - - src/core/lib/slice/slice_internal.h - - src/core/lib/slice/slice_refcount.h - - src/core/lib/slice/slice_string_helpers.h - - src/core/lib/surface/api_trace.h - - src/core/lib/surface/builtins.h - - src/core/lib/surface/call.h - - src/core/lib/surface/call_test_only.h - - src/core/lib/surface/call_trace.h - - src/core/lib/surface/channel.h - - src/core/lib/surface/channel_init.h - - src/core/lib/surface/channel_stack_type.h - - src/core/lib/surface/completion_queue.h - - src/core/lib/surface/completion_queue_factory.h - - src/core/lib/surface/event_string.h - - src/core/lib/surface/init.h - - src/core/lib/surface/init_internally.h - - src/core/lib/surface/lame_client.h - - src/core/lib/surface/server.h - - src/core/lib/surface/validate_metadata.h - - src/core/lib/surface/wait_for_cq_end_op.h - - src/core/lib/transport/batch_builder.h - - src/core/lib/transport/connectivity_state.h - - src/core/lib/transport/custom_metadata.h - - src/core/lib/transport/error_utils.h - - src/core/lib/transport/handshaker_factory.h - - src/core/lib/transport/handshaker_registry.h - - src/core/lib/transport/http2_errors.h - - src/core/lib/transport/metadata_batch.h - - src/core/lib/transport/metadata_compression_traits.h - - src/core/lib/transport/parsed_metadata.h - - src/core/lib/transport/simple_slice_based_metadata.h - - src/core/lib/transport/status_conversion.h - - src/core/lib/transport/timeout_encoding.h - - src/core/lib/transport/transport.h - - src/core/lib/transport/transport_fwd.h - - src/core/lib/uri/uri_parser.h - - src/core/tsi/alts/handshaker/transport_security_common_api.h - - third_party/upb/upb/base/internal/log2.h - - third_party/upb/upb/generated_code_support.h - - third_party/upb/upb/hash/common.h - - third_party/upb/upb/hash/int_table.h - - third_party/upb/upb/hash/str_table.h - - third_party/upb/upb/message/accessors.h - - third_party/upb/upb/message/array.h - - third_party/upb/upb/message/internal/accessors.h - - third_party/upb/upb/message/internal/array.h - - third_party/upb/upb/message/internal/extension.h - - third_party/upb/upb/message/internal/map.h - - third_party/upb/upb/message/internal/map_entry.h - - third_party/upb/upb/message/internal/map_sorter.h - - third_party/upb/upb/message/internal/message.h - - third_party/upb/upb/message/internal/types.h - - third_party/upb/upb/message/map.h - - third_party/upb/upb/message/map_gencode_util.h - - third_party/upb/upb/message/message.h - - third_party/upb/upb/message/tagged_ptr.h - - third_party/upb/upb/message/types.h - - third_party/upb/upb/message/value.h - - third_party/upb/upb/mini_descriptor/build_enum.h - - third_party/upb/upb/mini_descriptor/decode.h - - third_party/upb/upb/mini_descriptor/internal/base92.h - - third_party/upb/upb/mini_descriptor/internal/decoder.h - - third_party/upb/upb/mini_descriptor/internal/encode.h - - third_party/upb/upb/mini_descriptor/internal/encode.hpp - - third_party/upb/upb/mini_descriptor/internal/modifiers.h - - third_party/upb/upb/mini_descriptor/internal/wire_constants.h - - third_party/upb/upb/mini_descriptor/link.h - - third_party/upb/upb/mini_table/enum.h - - third_party/upb/upb/mini_table/extension.h - - third_party/upb/upb/mini_table/extension_registry.h - - third_party/upb/upb/mini_table/field.h - - third_party/upb/upb/mini_table/file.h - - third_party/upb/upb/mini_table/internal/enum.h - - third_party/upb/upb/mini_table/internal/extension.h - - third_party/upb/upb/mini_table/internal/field.h - - third_party/upb/upb/mini_table/internal/file.h - - third_party/upb/upb/mini_table/internal/message.h - - third_party/upb/upb/mini_table/internal/sub.h - - third_party/upb/upb/mini_table/message.h - - third_party/upb/upb/mini_table/sub.h - - third_party/upb/upb/wire/decode.h - - third_party/upb/upb/wire/decode_fast.h - - third_party/upb/upb/wire/encode.h - - third_party/upb/upb/wire/eps_copy_input_stream.h - - third_party/upb/upb/wire/internal/constants.h - - third_party/upb/upb/wire/internal/decode.h - - third_party/upb/upb/wire/internal/swap.h - - third_party/upb/upb/wire/reader.h - - third_party/upb/upb/wire/types.h - src: - - src/core/ext/transport/chaotic_good/frame.cc - - src/core/ext/transport/chaotic_good/frame_header.cc - - src/core/ext/transport/chttp2/transport/bin_encoder.cc - - src/core/ext/transport/chttp2/transport/decode_huff.cc - - src/core/ext/transport/chttp2/transport/hpack_encoder.cc - - src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc - - src/core/ext/transport/chttp2/transport/hpack_parse_result.cc - - src/core/ext/transport/chttp2/transport/hpack_parser.cc - - src/core/ext/transport/chttp2/transport/hpack_parser_table.cc - - src/core/ext/transport/chttp2/transport/http_trace.cc - - src/core/ext/transport/chttp2/transport/huffsyms.cc - - src/core/ext/transport/chttp2/transport/varint.cc - - src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c - - src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c - - src/core/ext/upb-gen/google/rpc/status.upb_minitable.c - - src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c - - src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c - - src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c - - src/core/lib/address_utils/parse_address.cc - - src/core/lib/address_utils/sockaddr_utils.cc - - src/core/lib/backoff/backoff.cc - - src/core/lib/backoff/random_early_detection.cc - - src/core/lib/channel/call_tracer.cc - - src/core/lib/channel/channel_args.cc - - src/core/lib/channel/channel_args_preconditioning.cc - - src/core/lib/channel/channel_stack.cc - - src/core/lib/channel/channel_stack_builder.cc - - src/core/lib/channel/channel_stack_builder_impl.cc - - src/core/lib/channel/channel_stack_trace.cc - - src/core/lib/channel/channel_trace.cc - - src/core/lib/channel/channelz.cc - - src/core/lib/channel/channelz_registry.cc - - src/core/lib/channel/connected_channel.cc - - src/core/lib/channel/promise_based_filter.cc - - src/core/lib/channel/server_call_tracer_filter.cc - - src/core/lib/channel/status_util.cc - - src/core/lib/compression/compression.cc - - src/core/lib/compression/compression_internal.cc - - src/core/lib/compression/message_compress.cc - - src/core/lib/config/core_configuration.cc - - src/core/lib/debug/event_log.cc - - src/core/lib/debug/histogram_view.cc - - src/core/lib/debug/stats.cc - - src/core/lib/debug/stats_data.cc - - src/core/lib/debug/trace.cc - - src/core/lib/event_engine/ares_resolver.cc - - src/core/lib/event_engine/cf_engine/cf_engine.cc - - src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc - - src/core/lib/event_engine/cf_engine/dns_service_resolver.cc - - src/core/lib/event_engine/channel_args_endpoint_config.cc - - src/core/lib/event_engine/default_event_engine.cc - - src/core/lib/event_engine/default_event_engine_factory.cc - - src/core/lib/event_engine/event_engine.cc - - src/core/lib/event_engine/forkable.cc - - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc - - src/core/lib/event_engine/posix_engine/ev_poll_posix.cc - - src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc - - src/core/lib/event_engine/posix_engine/internal_errqueue.cc - - src/core/lib/event_engine/posix_engine/lockfree_event.cc - - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc - - src/core/lib/event_engine/posix_engine/posix_endpoint.cc - - src/core/lib/event_engine/posix_engine/posix_engine.cc - - src/core/lib/event_engine/posix_engine/posix_engine_listener.cc - - src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc - - src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc - - src/core/lib/event_engine/posix_engine/timer.cc - - src/core/lib/event_engine/posix_engine/timer_heap.cc - - src/core/lib/event_engine/posix_engine/timer_manager.cc - - src/core/lib/event_engine/posix_engine/traced_buffer_list.cc - - src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc - - src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc - - src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc - - src/core/lib/event_engine/resolved_address.cc - - src/core/lib/event_engine/shim.cc - - src/core/lib/event_engine/slice.cc - - src/core/lib/event_engine/slice_buffer.cc - - src/core/lib/event_engine/tcp_socket_utils.cc - - src/core/lib/event_engine/thread_pool/thread_count.cc - - src/core/lib/event_engine/thread_pool/thread_pool_factory.cc - - src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc - - src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc - - src/core/lib/event_engine/time_util.cc - - src/core/lib/event_engine/trace.cc - - src/core/lib/event_engine/utils.cc - - src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc - - src/core/lib/event_engine/windows/iocp.cc - - src/core/lib/event_engine/windows/native_windows_dns_resolver.cc - - src/core/lib/event_engine/windows/win_socket.cc - - src/core/lib/event_engine/windows/windows_endpoint.cc - - src/core/lib/event_engine/windows/windows_engine.cc - - src/core/lib/event_engine/windows/windows_listener.cc - - src/core/lib/event_engine/work_queue/basic_work_queue.cc - - src/core/lib/experiments/config.cc - - src/core/lib/experiments/experiments.cc - - src/core/lib/gprpp/load_file.cc - - src/core/lib/gprpp/per_cpu.cc - - src/core/lib/gprpp/ref_counted_string.cc - - src/core/lib/gprpp/status_helper.cc - - src/core/lib/gprpp/time.cc - - src/core/lib/gprpp/time_averaged_stats.cc - - src/core/lib/gprpp/validation_errors.cc - - src/core/lib/gprpp/work_serializer.cc - - src/core/lib/handshaker/proxy_mapper_registry.cc - - src/core/lib/iomgr/buffer_list.cc - - src/core/lib/iomgr/call_combiner.cc - - src/core/lib/iomgr/cfstream_handle.cc - - src/core/lib/iomgr/closure.cc - - src/core/lib/iomgr/combiner.cc - - src/core/lib/iomgr/dualstack_socket_posix.cc - - src/core/lib/iomgr/endpoint.cc - - src/core/lib/iomgr/endpoint_cfstream.cc - - src/core/lib/iomgr/endpoint_pair_posix.cc - - src/core/lib/iomgr/endpoint_pair_windows.cc - - src/core/lib/iomgr/error.cc - - src/core/lib/iomgr/error_cfstream.cc - - src/core/lib/iomgr/ev_apple.cc - - src/core/lib/iomgr/ev_epoll1_linux.cc - - src/core/lib/iomgr/ev_poll_posix.cc - - src/core/lib/iomgr/ev_posix.cc - - src/core/lib/iomgr/ev_windows.cc - - src/core/lib/iomgr/event_engine_shims/closure.cc - - src/core/lib/iomgr/event_engine_shims/endpoint.cc - - src/core/lib/iomgr/event_engine_shims/tcp_client.cc - - src/core/lib/iomgr/exec_ctx.cc - - src/core/lib/iomgr/executor.cc - - src/core/lib/iomgr/fork_posix.cc - - src/core/lib/iomgr/fork_windows.cc - - src/core/lib/iomgr/gethostname_fallback.cc - - src/core/lib/iomgr/gethostname_host_name_max.cc - - src/core/lib/iomgr/gethostname_sysconf.cc - - src/core/lib/iomgr/grpc_if_nametoindex_posix.cc - - src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc - - src/core/lib/iomgr/internal_errqueue.cc - - src/core/lib/iomgr/iocp_windows.cc - - src/core/lib/iomgr/iomgr.cc - - src/core/lib/iomgr/iomgr_internal.cc - - src/core/lib/iomgr/iomgr_posix.cc - - src/core/lib/iomgr/iomgr_posix_cfstream.cc - - src/core/lib/iomgr/iomgr_windows.cc - - src/core/lib/iomgr/load_file.cc - - src/core/lib/iomgr/lockfree_event.cc - - src/core/lib/iomgr/polling_entity.cc - - src/core/lib/iomgr/pollset.cc - - src/core/lib/iomgr/pollset_set.cc - - src/core/lib/iomgr/pollset_set_windows.cc - - src/core/lib/iomgr/pollset_windows.cc - - src/core/lib/iomgr/resolve_address.cc - - src/core/lib/iomgr/resolve_address_posix.cc - - src/core/lib/iomgr/resolve_address_windows.cc - - src/core/lib/iomgr/sockaddr_utils_posix.cc - - src/core/lib/iomgr/socket_factory_posix.cc - - src/core/lib/iomgr/socket_mutator.cc - - src/core/lib/iomgr/socket_utils_common_posix.cc - - src/core/lib/iomgr/socket_utils_linux.cc - - src/core/lib/iomgr/socket_utils_posix.cc - - src/core/lib/iomgr/socket_utils_windows.cc - - src/core/lib/iomgr/socket_windows.cc - - src/core/lib/iomgr/systemd_utils.cc - - src/core/lib/iomgr/tcp_client.cc - - src/core/lib/iomgr/tcp_client_cfstream.cc - - src/core/lib/iomgr/tcp_client_posix.cc - - src/core/lib/iomgr/tcp_client_windows.cc - - src/core/lib/iomgr/tcp_posix.cc - - src/core/lib/iomgr/tcp_server.cc - - src/core/lib/iomgr/tcp_server_posix.cc - - src/core/lib/iomgr/tcp_server_utils_posix_common.cc - - src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc - - src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc - - src/core/lib/iomgr/tcp_server_windows.cc - - src/core/lib/iomgr/tcp_windows.cc - - src/core/lib/iomgr/timer.cc - - src/core/lib/iomgr/timer_generic.cc - - src/core/lib/iomgr/timer_heap.cc - - src/core/lib/iomgr/timer_manager.cc - - src/core/lib/iomgr/unix_sockets_posix.cc - - src/core/lib/iomgr/unix_sockets_posix_noop.cc - - src/core/lib/iomgr/vsock.cc - - src/core/lib/iomgr/wakeup_fd_eventfd.cc - - src/core/lib/iomgr/wakeup_fd_nospecial.cc - - src/core/lib/iomgr/wakeup_fd_pipe.cc - - src/core/lib/iomgr/wakeup_fd_posix.cc - - src/core/lib/json/json_writer.cc - - src/core/lib/load_balancing/lb_policy.cc - - src/core/lib/load_balancing/lb_policy_registry.cc - - src/core/lib/promise/activity.cc - - src/core/lib/promise/party.cc - - src/core/lib/promise/trace.cc - - src/core/lib/resolver/endpoint_addresses.cc - - src/core/lib/resolver/resolver.cc - - src/core/lib/resolver/resolver_registry.cc - - src/core/lib/resource_quota/api.cc - - src/core/lib/resource_quota/arena.cc - - src/core/lib/resource_quota/memory_quota.cc - - src/core/lib/resource_quota/periodic_update.cc - - src/core/lib/resource_quota/resource_quota.cc - - src/core/lib/resource_quota/thread_quota.cc - - src/core/lib/resource_quota/trace.cc - - src/core/lib/security/certificate_provider/certificate_provider_registry.cc - - src/core/lib/security/credentials/alts/check_gcp_environment.cc - - src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc - - src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc - - src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc - - src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc - - src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc - - src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc - - src/core/lib/service_config/service_config_parser.cc - - src/core/lib/slice/b64.cc - - src/core/lib/slice/percent_encoding.cc - - src/core/lib/slice/slice.cc - - src/core/lib/slice/slice_buffer.cc - - src/core/lib/slice/slice_refcount.cc - - src/core/lib/slice/slice_string_helpers.cc - - src/core/lib/surface/api_trace.cc - - src/core/lib/surface/builtins.cc - - src/core/lib/surface/byte_buffer.cc - - src/core/lib/surface/byte_buffer_reader.cc - - src/core/lib/surface/call.cc - - src/core/lib/surface/call_details.cc - - src/core/lib/surface/call_log_batch.cc - - src/core/lib/surface/call_trace.cc - - src/core/lib/surface/channel.cc - - src/core/lib/surface/channel_init.cc - - src/core/lib/surface/channel_ping.cc - - src/core/lib/surface/channel_stack_type.cc - - src/core/lib/surface/completion_queue.cc - - src/core/lib/surface/completion_queue_factory.cc - - src/core/lib/surface/event_string.cc - - src/core/lib/surface/init_internally.cc - - src/core/lib/surface/lame_client.cc - - src/core/lib/surface/metadata_array.cc - - src/core/lib/surface/server.cc - - src/core/lib/surface/validate_metadata.cc - - src/core/lib/surface/version.cc - - src/core/lib/transport/batch_builder.cc - - src/core/lib/transport/connectivity_state.cc - - src/core/lib/transport/error_utils.cc - - src/core/lib/transport/handshaker_registry.cc - - src/core/lib/transport/metadata_batch.cc - - src/core/lib/transport/parsed_metadata.cc - - src/core/lib/transport/status_conversion.cc - - src/core/lib/transport/timeout_encoding.cc - - src/core/lib/transport/transport.cc - - src/core/lib/transport/transport_op_string.cc - - src/core/lib/uri/uri_parser.cc - - src/core/tsi/alts/handshaker/transport_security_common_api.cc - - test/core/transport/chaotic_good/frame_test.cc - - third_party/upb/upb/hash/common.c - - third_party/upb/upb/message/accessors.c - - third_party/upb/upb/message/array.c - - third_party/upb/upb/message/map.c - - third_party/upb/upb/message/map_sorter.c - - third_party/upb/upb/message/message.c - - third_party/upb/upb/mini_descriptor/build_enum.c - - third_party/upb/upb/mini_descriptor/decode.c - - third_party/upb/upb/mini_descriptor/internal/base92.c - - third_party/upb/upb/mini_descriptor/internal/encode.c - - third_party/upb/upb/mini_descriptor/link.c - - third_party/upb/upb/mini_table/extension_registry.c - - third_party/upb/upb/mini_table/internal/message.c - - third_party/upb/upb/mini_table/message.c - - third_party/upb/upb/wire/decode.c - - third_party/upb/upb/wire/decode_fast.c - - third_party/upb/upb/wire/encode.c - - third_party/upb/upb/wire/eps_copy_input_stream.c - - third_party/upb/upb/wire/reader.c - deps: - - gtest - - upb - - utf8_range_lib - - z - - absl/cleanup:cleanup - - absl/container:flat_hash_map - - absl/container:inlined_vector - - absl/functional:function_ref - - absl/hash:hash - - absl/meta:type_traits - - absl/random:bit_gen_ref - - absl/random:distributions - - absl/status:statusor - - absl/types:span - - absl/utility:utility - - cares - - gpr -- name: test_core_transport_chttp2_frame_test - gtest: true - build: test - language: c++ - headers: - - src/core/ext/transport/chttp2/transport/frame.h - - src/core/lib/debug/trace.h - - src/core/lib/slice/slice.h - - src/core/lib/slice/slice_buffer.h - - src/core/lib/slice/slice_internal.h - - src/core/lib/slice/slice_refcount.h - - src/core/lib/slice/slice_string_helpers.h - - src/core/lib/transport/http2_errors.h - src: - - src/core/ext/transport/chttp2/transport/frame.cc - - src/core/lib/debug/trace.cc - - src/core/lib/slice/slice.cc - - src/core/lib/slice/slice_buffer.cc - - src/core/lib/slice/slice_refcount.cc - - src/core/lib/slice/slice_string_helpers.cc - - test/core/transport/chttp2/frame_test.cc - deps: - - gtest - - absl/hash:hash - - absl/status:statusor - - absl/types:span - - gpr - uses_polling: false - name: test_cpp_client_credentials_test gtest: true build: test diff --git a/tools/buildgen/extract_metadata_from_bazel_xml.py b/tools/buildgen/extract_metadata_from_bazel_xml.py index f8bd3595482..18471eb1d8b 100755 --- a/tools/buildgen/extract_metadata_from_bazel_xml.py +++ b/tools/buildgen/extract_metadata_from_bazel_xml.py @@ -895,6 +895,13 @@ def _exclude_unwanted_cc_tests(tests: List[str]) -> List[str]: if not test.startswith("test/cpp/util:channelz_sampler_test") ] + # chaotic good not supported outside bazel + tests = [ + test + for test in tests + if not test.startswith("test/core/transport/chaotic_good") + ] + # we don't need to generate fuzzers outside of bazel tests = [test for test in tests if not test.endswith("_fuzzer")] diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index ec2448a67c1..a8edaa5d45a 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2253,54 +2253,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "client_transport_error_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "client_transport_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, { "args": [], "benchmark": false, @@ -3840,14 +3792,14 @@ "flaky": false, "gtest": true, "language": "c++", - "name": "frame_header_test", + "name": "frame_test", "platforms": [ "linux", "mac", "posix", "windows" ], - "uses_polling": true + "uses_polling": false }, { "args": [], @@ -9095,30 +9047,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "server_transport_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, { "args": [], "benchmark": false, @@ -10491,54 +10419,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "test_core_transport_chaotic_good_frame_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "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": "test_core_transport_chttp2_frame_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, { "args": [], "benchmark": false, From 3f8af9a74c11bf37c9ed4dd5b4fb28166667e44a Mon Sep 17 00:00:00 2001 From: AJ Heller Date: Tue, 9 Jan 2024 13:52:06 -0800 Subject: [PATCH 23/27] [EventEngine] Rename Posix native resolver (#35491) Closes #35491 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35491 from drfloob:cleanup-posix-ee-native-resolver 1c97ff5216a8e5d6873a70ec9f1cf0c43b6f4e27 PiperOrigin-RevId: 597035026 --- CMakeLists.txt | 6 +++--- Makefile | 4 ++-- Package.swift | 4 ++-- build_autogenerated.yaml | 12 ++++++------ config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 6 +++--- grpc.gemspec | 4 ++-- grpc.gyp | 6 +++--- package.xml | 4 ++-- src/core/BUILD | 8 ++++---- ...dns_resolver.cc => native_posix_dns_resolver.cc} | 11 ++++++----- ...e_dns_resolver.h => native_posix_dns_resolver.h} | 10 +++++----- .../lib/event_engine/posix_engine/posix_engine.cc | 8 ++++---- src/php/tests/MemoryLeakTest/ignore_leaks.supp | 13 ------------- src/python/grpcio/grpc_core_dependencies.py | 2 +- tools/doxygen/Doxyfile.c++.internal | 4 ++-- tools/doxygen/Doxyfile.core.internal | 4 ++-- 19 files changed, 51 insertions(+), 63 deletions(-) rename src/core/lib/event_engine/posix_engine/{native_dns_resolver.cc => native_posix_dns_resolver.cc} (93%) rename src/core/lib/event_engine/posix_engine/{native_dns_resolver.h => native_posix_dns_resolver.h} (81%) delete mode 100644 src/php/tests/MemoryLeakTest/ignore_leaks.supp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d544e34f75..bd67b71673e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2249,7 +2249,7 @@ add_library(grpc src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc src/core/lib/event_engine/posix_engine/internal_errqueue.cc src/core/lib/event_engine/posix_engine/lockfree_event.cc - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc + src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc src/core/lib/event_engine/posix_engine/posix_endpoint.cc src/core/lib/event_engine/posix_engine/posix_engine.cc src/core/lib/event_engine/posix_engine/posix_engine_listener.cc @@ -2981,7 +2981,7 @@ add_library(grpc_unsecure src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc src/core/lib/event_engine/posix_engine/internal_errqueue.cc src/core/lib/event_engine/posix_engine/lockfree_event.cc - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc + src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc src/core/lib/event_engine/posix_engine/posix_endpoint.cc src/core/lib/event_engine/posix_engine/posix_engine.cc src/core/lib/event_engine/posix_engine/posix_engine_listener.cc @@ -4971,7 +4971,7 @@ add_library(grpc_authorization_provider src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc src/core/lib/event_engine/posix_engine/internal_errqueue.cc src/core/lib/event_engine/posix_engine/lockfree_event.cc - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc + src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc src/core/lib/event_engine/posix_engine/posix_endpoint.cc src/core/lib/event_engine/posix_engine/posix_engine.cc src/core/lib/event_engine/posix_engine/posix_engine_listener.cc diff --git a/Makefile b/Makefile index b7224ba266b..6b741178ac3 100644 --- a/Makefile +++ b/Makefile @@ -1453,7 +1453,7 @@ LIBGRPC_SRC = \ src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \ src/core/lib/event_engine/posix_engine/internal_errqueue.cc \ src/core/lib/event_engine/posix_engine/lockfree_event.cc \ - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \ + src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \ src/core/lib/event_engine/posix_engine/posix_endpoint.cc \ src/core/lib/event_engine/posix_engine/posix_engine.cc \ src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \ @@ -2035,7 +2035,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \ src/core/lib/event_engine/posix_engine/internal_errqueue.cc \ src/core/lib/event_engine/posix_engine/lockfree_event.cc \ - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \ + src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \ src/core/lib/event_engine/posix_engine/posix_endpoint.cc \ src/core/lib/event_engine/posix_engine/posix_engine.cc \ src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \ diff --git a/Package.swift b/Package.swift index 06646df8e87..45407ba6dbc 100644 --- a/Package.swift +++ b/Package.swift @@ -1284,8 +1284,8 @@ let package = Package( "src/core/lib/event_engine/posix_engine/internal_errqueue.h", "src/core/lib/event_engine/posix_engine/lockfree_event.cc", "src/core/lib/event_engine/posix_engine/lockfree_event.h", - "src/core/lib/event_engine/posix_engine/native_dns_resolver.cc", - "src/core/lib/event_engine/posix_engine/native_dns_resolver.h", + "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc", + "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h", "src/core/lib/event_engine/posix_engine/posix_endpoint.cc", "src/core/lib/event_engine/posix_engine/posix_endpoint.h", "src/core/lib/event_engine/posix_engine/posix_engine.cc", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 4eecb357b2f..f3ca12108f4 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -883,7 +883,7 @@ libs: - src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h - src/core/lib/event_engine/posix_engine/internal_errqueue.h - src/core/lib/event_engine/posix_engine/lockfree_event.h - - src/core/lib/event_engine/posix_engine/native_dns_resolver.h + - src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h - src/core/lib/event_engine/posix_engine/posix_endpoint.h - src/core/lib/event_engine/posix_engine/posix_engine.h - src/core/lib/event_engine/posix_engine/posix_engine_closure.h @@ -1713,7 +1713,7 @@ libs: - src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc - src/core/lib/event_engine/posix_engine/internal_errqueue.cc - src/core/lib/event_engine/posix_engine/lockfree_event.cc - - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc + - src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc - src/core/lib/event_engine/posix_engine/posix_endpoint.cc - src/core/lib/event_engine/posix_engine/posix_engine.cc - src/core/lib/event_engine/posix_engine/posix_engine_listener.cc @@ -2350,7 +2350,7 @@ libs: - src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h - src/core/lib/event_engine/posix_engine/internal_errqueue.h - src/core/lib/event_engine/posix_engine/lockfree_event.h - - src/core/lib/event_engine/posix_engine/native_dns_resolver.h + - src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h - src/core/lib/event_engine/posix_engine/posix_endpoint.h - src/core/lib/event_engine/posix_engine/posix_engine.h - src/core/lib/event_engine/posix_engine/posix_engine_closure.h @@ -2803,7 +2803,7 @@ libs: - src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc - src/core/lib/event_engine/posix_engine/internal_errqueue.cc - src/core/lib/event_engine/posix_engine/lockfree_event.cc - - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc + - src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc - src/core/lib/event_engine/posix_engine/posix_endpoint.cc - src/core/lib/event_engine/posix_engine/posix_engine.cc - src/core/lib/event_engine/posix_engine/posix_engine_listener.cc @@ -4494,7 +4494,7 @@ libs: - src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h - src/core/lib/event_engine/posix_engine/internal_errqueue.h - src/core/lib/event_engine/posix_engine/lockfree_event.h - - src/core/lib/event_engine/posix_engine/native_dns_resolver.h + - src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h - src/core/lib/event_engine/posix_engine/posix_endpoint.h - src/core/lib/event_engine/posix_engine/posix_engine.h - src/core/lib/event_engine/posix_engine/posix_engine_closure.h @@ -4853,7 +4853,7 @@ libs: - src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc - src/core/lib/event_engine/posix_engine/internal_errqueue.cc - src/core/lib/event_engine/posix_engine/lockfree_event.cc - - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc + - src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc - src/core/lib/event_engine/posix_engine/posix_endpoint.cc - src/core/lib/event_engine/posix_engine/posix_engine.cc - src/core/lib/event_engine/posix_engine/posix_engine_listener.cc diff --git a/config.m4 b/config.m4 index 74d0f802315..a0d3549d7f0 100644 --- a/config.m4 +++ b/config.m4 @@ -542,7 +542,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \ src/core/lib/event_engine/posix_engine/internal_errqueue.cc \ src/core/lib/event_engine/posix_engine/lockfree_event.cc \ - src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \ + src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \ src/core/lib/event_engine/posix_engine/posix_endpoint.cc \ src/core/lib/event_engine/posix_engine/posix_engine.cc \ src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \ diff --git a/config.w32 b/config.w32 index afc9589aed3..ea2a72452f0 100644 --- a/config.w32 +++ b/config.w32 @@ -507,7 +507,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\event_engine\\posix_engine\\event_poller_posix_default.cc " + "src\\core\\lib\\event_engine\\posix_engine\\internal_errqueue.cc " + "src\\core\\lib\\event_engine\\posix_engine\\lockfree_event.cc " + - "src\\core\\lib\\event_engine\\posix_engine\\native_dns_resolver.cc " + + "src\\core\\lib\\event_engine\\posix_engine\\native_posix_dns_resolver.cc " + "src\\core\\lib\\event_engine\\posix_engine\\posix_endpoint.cc " + "src\\core\\lib\\event_engine\\posix_engine\\posix_engine.cc " + "src\\core\\lib\\event_engine\\posix_engine\\posix_engine_listener.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0c39f744fb0..a3592151f05 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -955,7 +955,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h', 'src/core/lib/event_engine/posix_engine/internal_errqueue.h', 'src/core/lib/event_engine/posix_engine/lockfree_event.h', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.h', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h', 'src/core/lib/event_engine/posix_engine/posix_endpoint.h', 'src/core/lib/event_engine/posix_engine/posix_engine.h', 'src/core/lib/event_engine/posix_engine/posix_engine_closure.h', @@ -2197,7 +2197,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h', 'src/core/lib/event_engine/posix_engine/internal_errqueue.h', 'src/core/lib/event_engine/posix_engine/lockfree_event.h', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.h', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h', 'src/core/lib/event_engine/posix_engine/posix_endpoint.h', 'src/core/lib/event_engine/posix_engine/posix_engine.h', 'src/core/lib/event_engine/posix_engine/posix_engine_closure.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index a700bdbec44..259a7473601 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1387,8 +1387,8 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/posix_engine/internal_errqueue.h', 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', 'src/core/lib/event_engine/posix_engine/lockfree_event.h', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.h', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h', 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', 'src/core/lib/event_engine/posix_engine/posix_endpoint.h', 'src/core/lib/event_engine/posix_engine/posix_engine.cc', @@ -2964,7 +2964,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h', 'src/core/lib/event_engine/posix_engine/internal_errqueue.h', 'src/core/lib/event_engine/posix_engine/lockfree_event.h', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.h', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h', 'src/core/lib/event_engine/posix_engine/posix_endpoint.h', 'src/core/lib/event_engine/posix_engine/posix_engine.h', 'src/core/lib/event_engine/posix_engine/posix_engine_closure.h', diff --git a/grpc.gemspec b/grpc.gemspec index bfd2ac83bca..18146192284 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1290,8 +1290,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/event_engine/posix_engine/internal_errqueue.h ) s.files += %w( src/core/lib/event_engine/posix_engine/lockfree_event.cc ) s.files += %w( src/core/lib/event_engine/posix_engine/lockfree_event.h ) - s.files += %w( src/core/lib/event_engine/posix_engine/native_dns_resolver.cc ) - s.files += %w( src/core/lib/event_engine/posix_engine/native_dns_resolver.h ) + s.files += %w( src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc ) + s.files += %w( src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h ) s.files += %w( src/core/lib/event_engine/posix_engine/posix_endpoint.cc ) s.files += %w( src/core/lib/event_engine/posix_engine/posix_endpoint.h ) s.files += %w( src/core/lib/event_engine/posix_engine/posix_engine.cc ) diff --git a/grpc.gyp b/grpc.gyp index 1a33c9eb586..e87ec7dcba8 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -772,7 +772,7 @@ 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', 'src/core/lib/event_engine/posix_engine/posix_engine.cc', 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', @@ -1295,7 +1295,7 @@ 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', 'src/core/lib/event_engine/posix_engine/posix_engine.cc', 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', @@ -2075,7 +2075,7 @@ 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', 'src/core/lib/event_engine/posix_engine/posix_engine.cc', 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', diff --git a/package.xml b/package.xml index 885bedac415..436443d9097 100644 --- a/package.xml +++ b/package.xml @@ -1272,8 +1272,8 @@ - - + + diff --git a/src/core/BUILD b/src/core/BUILD index 37a65c4b32b..d76984d9a33 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2175,7 +2175,7 @@ grpc_cc_library( "forkable", "init_internally", "iomgr_port", - "native_dns_resolver", + "native_posix_dns_resolver", "no_destruct", "posix_event_engine_base_hdrs", "posix_event_engine_closure", @@ -2535,12 +2535,12 @@ grpc_cc_library( ) grpc_cc_library( - name = "native_dns_resolver", + name = "native_posix_dns_resolver", srcs = [ - "lib/event_engine/posix_engine/native_dns_resolver.cc", + "lib/event_engine/posix_engine/native_posix_dns_resolver.cc", ], hdrs = [ - "lib/event_engine/posix_engine/native_dns_resolver.h", + "lib/event_engine/posix_engine/native_posix_dns_resolver.h", ], external_deps = [ "absl/functional:any_invocable", diff --git a/src/core/lib/event_engine/posix_engine/native_dns_resolver.cc b/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc similarity index 93% rename from src/core/lib/event_engine/posix_engine/native_dns_resolver.cc rename to src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc index 79a9489d661..344471564e1 100644 --- a/src/core/lib/event_engine/posix_engine/native_dns_resolver.cc +++ b/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc @@ -33,7 +33,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" -#include "src/core/lib/event_engine/posix_engine/native_dns_resolver.h" +#include "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/host_port.h" @@ -93,10 +93,11 @@ LookupHostnameBlocking(absl::string_view name, absl::string_view default_port) { } // namespace -NativeDNSResolver::NativeDNSResolver(std::shared_ptr event_engine) +NativePosixDNSResolver::NativePosixDNSResolver( + std::shared_ptr event_engine) : event_engine_(std::move(event_engine)) {} -void NativeDNSResolver::LookupHostname( +void NativePosixDNSResolver::LookupHostname( EventEngine::DNSResolver::LookupHostnameCallback on_resolved, absl::string_view name, absl::string_view default_port) { event_engine_->Run( @@ -105,7 +106,7 @@ void NativeDNSResolver::LookupHostname( }); } -void NativeDNSResolver::LookupSRV( +void NativePosixDNSResolver::LookupSRV( EventEngine::DNSResolver::LookupSRVCallback on_resolved, absl::string_view /* name */) { // Not supported @@ -115,7 +116,7 @@ void NativeDNSResolver::LookupSRV( }); } -void NativeDNSResolver::LookupTXT( +void NativePosixDNSResolver::LookupTXT( EventEngine::DNSResolver::LookupTXTCallback on_resolved, absl::string_view /* name */) { // Not supported diff --git a/src/core/lib/event_engine/posix_engine/native_dns_resolver.h b/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h similarity index 81% rename from src/core/lib/event_engine/posix_engine/native_dns_resolver.h rename to src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h index 411b090ab64..651b01866f8 100644 --- a/src/core/lib/event_engine/posix_engine/native_dns_resolver.h +++ b/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_DNS_RESOLVER_H -#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_DNS_RESOLVER_H +#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_POSIX_DNS_RESOLVER_H +#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_POSIX_DNS_RESOLVER_H #include @@ -34,9 +34,9 @@ namespace experimental { // An asynchronous DNS resolver which uses the native platform's getaddrinfo // API. Only supports A/AAAA records. -class NativeDNSResolver : public RefCountedDNSResolverInterface { +class NativePosixDNSResolver : public RefCountedDNSResolverInterface { public: - explicit NativeDNSResolver(std::shared_ptr event_engine); + explicit NativePosixDNSResolver(std::shared_ptr event_engine); void LookupHostname( EventEngine::DNSResolver::LookupHostnameCallback on_resolved, @@ -58,4 +58,4 @@ class NativeDNSResolver : public RefCountedDNSResolverInterface { } // namespace grpc_event_engine #endif // GRPC_POSIX_SOCKET_RESOLVE_ADDRESS -#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_DNS_RESOLVER_H +#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_POSIX_DNS_RESOLVER_H 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 06938a6204a..9991135cd71 100644 --- a/src/core/lib/event_engine/posix_engine/posix_engine.cc +++ b/src/core/lib/event_engine/posix_engine/posix_engine.cc @@ -45,7 +45,7 @@ #include "src/core/lib/event_engine/poller.h" #include "src/core/lib/event_engine/posix.h" #include "src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h" -#include "src/core/lib/event_engine/posix_engine/native_dns_resolver.h" +#include "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h" #include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/posix_engine/timer.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" @@ -571,10 +571,10 @@ PosixEventEngine::GetDNSResolver( std::move(*ares_resolver)); #endif // GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) } - GRPC_EVENT_ENGINE_DNS_TRACE("PosixEventEngine:%p creating NativeDNSResolver", - this); + GRPC_EVENT_ENGINE_DNS_TRACE( + "PosixEventEngine:%p creating NativePosixDNSResolver", this); return std::make_unique( - grpc_core::MakeOrphanable(shared_from_this())); + grpc_core::MakeOrphanable(shared_from_this())); #endif // GRPC_POSIX_SOCKET_RESOLVE_ADDRESS } diff --git a/src/php/tests/MemoryLeakTest/ignore_leaks.supp b/src/php/tests/MemoryLeakTest/ignore_leaks.supp deleted file mode 100644 index dccd088d905..00000000000 --- a/src/php/tests/MemoryLeakTest/ignore_leaks.supp +++ /dev/null @@ -1,13 +0,0 @@ -{ - static Posix NativeDNSResolver - Memcheck:Leak - match-leak-kinds: possible - ... - fun:pthread_create@@GLIBC_2.2.5 - ... - fun:_ZN17grpc_event_engine12experimental21GetDefaultEventEngineEv - fun:_ZN9grpc_core17NativeDNSResolverC1Ev - fun:_ZN9grpc_core17NativeDNSResolver11GetOrCreateEv - ... -} - diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 30a62ced196..c659b30d108 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -516,7 +516,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', - 'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', 'src/core/lib/event_engine/posix_engine/posix_engine.cc', 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 168ddf984d8..5e27de762f9 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2289,8 +2289,8 @@ src/core/lib/event_engine/posix_engine/internal_errqueue.cc \ src/core/lib/event_engine/posix_engine/internal_errqueue.h \ src/core/lib/event_engine/posix_engine/lockfree_event.cc \ src/core/lib/event_engine/posix_engine/lockfree_event.h \ -src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \ -src/core/lib/event_engine/posix_engine/native_dns_resolver.h \ +src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \ +src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h \ src/core/lib/event_engine/posix_engine/posix_endpoint.cc \ src/core/lib/event_engine/posix_engine/posix_endpoint.h \ src/core/lib/event_engine/posix_engine/posix_engine.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 8b439b3ac66..c220a387917 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -2065,8 +2065,8 @@ src/core/lib/event_engine/posix_engine/internal_errqueue.cc \ src/core/lib/event_engine/posix_engine/internal_errqueue.h \ src/core/lib/event_engine/posix_engine/lockfree_event.cc \ src/core/lib/event_engine/posix_engine/lockfree_event.h \ -src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \ -src/core/lib/event_engine/posix_engine/native_dns_resolver.h \ +src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \ +src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h \ src/core/lib/event_engine/posix_engine/posix_endpoint.cc \ src/core/lib/event_engine/posix_engine/posix_endpoint.h \ src/core/lib/event_engine/posix_engine/posix_engine.cc \ From 4105425da5ae891c252f7d9ae693cbeec3ac7e74 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Jan 2024 14:09:09 -0800 Subject: [PATCH 24/27] [call-v3] Convert ClientAuthorityFilter (#35469) Closes #35469 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35469 from ctiller:caf 1dffe24fcbafa6854cdccdc91d29dae5f0a509a0 PiperOrigin-RevId: 597040037 --- .../filters/http/client_authority_filter.cc | 19 ++++++++++--------- .../filters/http/client_authority_filter.h | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 973079e4db2..3df6d275f6a 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -37,6 +37,12 @@ namespace grpc_core { +const NoInterceptor ClientAuthorityFilter::Call::OnServerInitialMetadata; +const NoInterceptor ClientAuthorityFilter::Call::OnServerTrailingMetadata; +const NoInterceptor ClientAuthorityFilter::Call::OnClientToServerMessage; +const NoInterceptor ClientAuthorityFilter::Call::OnServerToClientMessage; +const NoInterceptor ClientAuthorityFilter::Call::OnFinalize; + absl::StatusOr ClientAuthorityFilter::Create( const ChannelArgs& args, ChannelFilter::Args) { absl::optional default_authority = @@ -49,17 +55,12 @@ absl::StatusOr ClientAuthorityFilter::Create( return ClientAuthorityFilter(Slice::FromCopiedString(*default_authority)); } -ArenaPromise ClientAuthorityFilter::MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) { +void ClientAuthorityFilter::Call::OnClientInitialMetadata( + ClientMetadata& md, ClientAuthorityFilter* filter) { // If no authority is set, set the default authority. - if (call_args.client_initial_metadata->get_pointer(HttpAuthorityMetadata()) == - nullptr) { - call_args.client_initial_metadata->Set(HttpAuthorityMetadata(), - default_authority_.Ref()); + if (md.get_pointer(HttpAuthorityMetadata()) == nullptr) { + md.Set(HttpAuthorityMetadata(), filter->default_authority_.Ref()); } - // We have no asynchronous work, so we can just ask the next promise to run, - // passing down initial_metadata. - return next_promise_factory(std::move(call_args)); } const grpc_channel_filter ClientAuthorityFilter::kFilter = diff --git a/src/core/ext/filters/http/client_authority_filter.h b/src/core/ext/filters/http/client_authority_filter.h index 930e1731e5e..064e0a0a450 100644 --- a/src/core/ext/filters/http/client_authority_filter.h +++ b/src/core/ext/filters/http/client_authority_filter.h @@ -34,16 +34,24 @@ namespace grpc_core { -class ClientAuthorityFilter final : public ChannelFilter { +class ClientAuthorityFilter final + : public ImplementChannelFilter { public: static const grpc_channel_filter kFilter; static absl::StatusOr Create(const ChannelArgs& args, ChannelFilter::Args); - // Construct a promise for one call. - ArenaPromise MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) override; + class Call { + public: + void OnClientInitialMetadata(ClientMetadata& md, + ClientAuthorityFilter* filter); + static const NoInterceptor OnServerInitialMetadata; + static const NoInterceptor OnServerTrailingMetadata; + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + static const NoInterceptor OnFinalize; + }; private: explicit ClientAuthorityFilter(Slice default_authority) From 5150b2346d4a49536681d9ef2bcbce9c81d424db Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Jan 2024 14:09:22 -0800 Subject: [PATCH 25/27] [call-v3] Move server load reporting filter to new api (#35471) Closes #35471 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35471 from ctiller:slrf b9e685c1c187e2acbfe9ae14dea7223af3ca5359 PiperOrigin-RevId: 597040097 --- .../server_load_reporting_filter.cc | 128 ++++++++---------- .../server_load_reporting_filter.h | 22 ++- src/core/lib/channel/promise_based_filter.h | 43 +++++- 3 files changed, 116 insertions(+), 77 deletions(-) diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc index 8a3ea08549b..4957d05ddaa 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc @@ -72,6 +72,10 @@ constexpr char kEncodedIpv4AddressLengthString[] = "08"; constexpr char kEncodedIpv6AddressLengthString[] = "32"; constexpr char kEmptyAddressLengthString[] = "00"; +const NoInterceptor ServerLoadReportingFilter::Call::OnServerInitialMetadata; +const NoInterceptor ServerLoadReportingFilter::Call::OnClientToServerMessage; +const NoInterceptor ServerLoadReportingFilter::Call::OnServerToClientMessage; + absl::StatusOr ServerLoadReportingFilter::Create( const ChannelArgs& channel_args, ChannelFilter::Args) { // Find and record the peer_identity. @@ -93,9 +97,9 @@ absl::StatusOr ServerLoadReportingFilter::Create( namespace { std::string GetCensusSafeClientIpString( - const ClientMetadataHandle& initial_metadata) { + const ClientMetadata& initial_metadata) { // Find the client URI string. - Slice* client_uri_slice = initial_metadata->get_pointer(PeerString()); + const Slice* client_uri_slice = initial_metadata.get_pointer(PeerString()); if (client_uri_slice == nullptr) { gpr_log(GPR_ERROR, "Unable to extract client URI string (peer string) from gRPC " @@ -139,8 +143,8 @@ std::string GetCensusSafeClientIpString( } } -std::string MakeClientIpAndLrToken( - absl::string_view lr_token, const ClientMetadataHandle& initial_metadata) { +std::string MakeClientIpAndLrToken(absl::string_view lr_token, + const ClientMetadata& initial_metadata) { std::string client_ip = GetCensusSafeClientIpString(initial_metadata); absl::string_view prefix; switch (client_ip.length()) { @@ -176,82 +180,68 @@ const char* GetStatusTagForStatus(grpc_status_code status) { } } // namespace -ArenaPromise ServerLoadReportingFilter::MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) { +void ServerLoadReportingFilter::Call::OnClientInitialMetadata( + ClientMetadata& md, ServerLoadReportingFilter* filter) { // Gather up basic facts about the request Slice service_method; - if (const Slice* path = - call_args.client_initial_metadata->get_pointer(HttpPathMetadata())) { + if (const Slice* path = md.get_pointer(HttpPathMetadata())) { service_method = path->Ref(); } - std::string target_host; - if (const Slice* authority = call_args.client_initial_metadata->get_pointer( - HttpAuthorityMetadata())) { - target_host = absl::AsciiStrToLower(authority->as_string_view()); + if (const Slice* authority = md.get_pointer(HttpAuthorityMetadata())) { + target_host_ = absl::AsciiStrToLower(authority->as_string_view()); } - std::string client_ip_and_lr_token; - auto lb_token = call_args.client_initial_metadata->Take(LbTokenMetadata()) - .value_or(Slice()); - client_ip_and_lr_token = MakeClientIpAndLrToken( - lb_token.as_string_view(), call_args.client_initial_metadata); + auto lb_token = md.Take(LbTokenMetadata()).value_or(Slice()); + client_ip_and_lr_token_ = + MakeClientIpAndLrToken(lb_token.as_string_view(), md); // Record the beginning of the request opencensus::stats::Record( {{::grpc::load_reporter::MeasureStartCount(), 1}}, {{::grpc::load_reporter::TagKeyToken(), - {client_ip_and_lr_token.data(), client_ip_and_lr_token.length()}}, + {client_ip_and_lr_token_.data(), client_ip_and_lr_token_.length()}}, {::grpc::load_reporter::TagKeyHost(), - {target_host.data(), target_host.length()}}, + {target_host_.data(), target_host_.length()}}, {::grpc::load_reporter::TagKeyUserId(), - {peer_identity_.data(), peer_identity_.length()}}}); - // Returned promise runs the rest of the request, then reports costs and - // records measurements - return ArenaPromise(Seq( - // Call down the stack - next_promise_factory(std::move(call_args)), - // And then record the call result - [this, client_ip_and_lr_token, - target_host](ServerMetadataHandle trailing_metadata) { - const auto& costs = trailing_metadata->Take(LbCostBinMetadata()); - for (const auto& cost : costs) { - opencensus::stats::Record( - {{::grpc::load_reporter::MeasureOtherCallMetric(), cost.cost}}, - {{::grpc::load_reporter::TagKeyToken(), - {client_ip_and_lr_token.data(), - client_ip_and_lr_token.length()}}, - {::grpc::load_reporter::TagKeyHost(), - {target_host.data(), target_host.length()}}, - {::grpc::load_reporter::TagKeyUserId(), - {peer_identity_.data(), peer_identity_.length()}}, - {::grpc::load_reporter::TagKeyMetricName(), - {cost.name.data(), cost.name.length()}}}); - } - GetContext()->Add([this, client_ip_and_lr_token, - target_host]( - const grpc_call_final_info* - final_info) { - if (final_info == nullptr) return; - // After the last bytes have been placed on the wire we record - // final measurements - opencensus::stats::Record( - {{::grpc::load_reporter::MeasureEndCount(), 1}, - {::grpc::load_reporter::MeasureEndBytesSent(), - final_info->stats.transport_stream_stats.outgoing.data_bytes}, - {::grpc::load_reporter::MeasureEndBytesReceived(), - final_info->stats.transport_stream_stats.incoming.data_bytes}, - {::grpc::load_reporter::MeasureEndLatencyMs(), - gpr_time_to_millis(final_info->stats.latency)}}, - {{::grpc::load_reporter::TagKeyToken(), - {client_ip_and_lr_token.data(), - client_ip_and_lr_token.length()}}, - {::grpc::load_reporter::TagKeyHost(), - {target_host.data(), target_host.length()}}, - {::grpc::load_reporter::TagKeyUserId(), - {peer_identity_.data(), peer_identity_.length()}}, - {::grpc::load_reporter::TagKeyStatus(), - GetStatusTagForStatus(final_info->final_status)}}); - }); - return Immediate(std::move(trailing_metadata)); - })); + {filter->peer_identity_.data(), filter->peer_identity_.length()}}}); +} + +void ServerLoadReportingFilter::Call::OnServerTrailingMetadata( + ServerMetadata& md, ServerLoadReportingFilter* filter) { + const auto& costs = md.Take(LbCostBinMetadata()); + for (const auto& cost : costs) { + opencensus::stats::Record( + {{::grpc::load_reporter::MeasureOtherCallMetric(), cost.cost}}, + {{::grpc::load_reporter::TagKeyToken(), + {client_ip_and_lr_token_.data(), client_ip_and_lr_token_.length()}}, + {::grpc::load_reporter::TagKeyHost(), + {target_host_.data(), target_host_.length()}}, + {::grpc::load_reporter::TagKeyUserId(), + {filter->peer_identity_.data(), filter->peer_identity_.length()}}, + {::grpc::load_reporter::TagKeyMetricName(), + {cost.name.data(), cost.name.length()}}}); + } +} + +void ServerLoadReportingFilter::Call::OnFinalize( + const grpc_call_final_info* final_info, ServerLoadReportingFilter* filter) { + if (final_info == nullptr) return; + // After the last bytes have been placed on the wire we record + // final measurements + opencensus::stats::Record( + {{::grpc::load_reporter::MeasureEndCount(), 1}, + {::grpc::load_reporter::MeasureEndBytesSent(), + final_info->stats.transport_stream_stats.outgoing.data_bytes}, + {::grpc::load_reporter::MeasureEndBytesReceived(), + final_info->stats.transport_stream_stats.incoming.data_bytes}, + {::grpc::load_reporter::MeasureEndLatencyMs(), + gpr_time_to_millis(final_info->stats.latency)}}, + {{::grpc::load_reporter::TagKeyToken(), + {client_ip_and_lr_token_.data(), client_ip_and_lr_token_.length()}}, + {::grpc::load_reporter::TagKeyHost(), + {target_host_.data(), target_host_.length()}}, + {::grpc::load_reporter::TagKeyUserId(), + {filter->peer_identity_.data(), filter->peer_identity_.length()}}, + {::grpc::load_reporter::TagKeyStatus(), + GetStatusTagForStatus(final_info->final_status)}}); } namespace { diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.h b/src/core/ext/filters/load_reporting/server_load_reporting_filter.h index 049a70eb07c..f3b8a04db08 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.h +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.h @@ -34,7 +34,8 @@ namespace grpc_core { -class ServerLoadReportingFilter : public ChannelFilter { +class ServerLoadReportingFilter + : public ImplementChannelFilter { public: static absl::StatusOr Create( const ChannelArgs& args, ChannelFilter::Args); @@ -43,9 +44,22 @@ class ServerLoadReportingFilter : public ChannelFilter { const char* peer_identity() { return peer_identity_.c_str(); } size_t peer_identity_len() { return peer_identity_.length(); } - // Construct a promise for one call. - ArenaPromise MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) override; + class Call { + public: + void OnClientInitialMetadata(ClientMetadata& md, + ServerLoadReportingFilter* filter); + static const NoInterceptor OnServerInitialMetadata; + void OnServerTrailingMetadata(ServerMetadata& md, + ServerLoadReportingFilter* filter); + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + void OnFinalize(const grpc_call_final_info* final_info, + ServerLoadReportingFilter* filter); + + private: + std::string client_ip_and_lr_token_; + std::string target_host_; + }; private: // The peer's authenticated identity. diff --git a/src/core/lib/channel/promise_based_filter.h b/src/core/lib/channel/promise_based_filter.h index 898970d1f48..d33cf38c096 100644 --- a/src/core/lib/channel/promise_based_filter.h +++ b/src/core/lib/channel/promise_based_filter.h @@ -331,6 +331,16 @@ auto MapResult(void (Derived::Call::*fn)(ServerMetadata&), Promise x, }); } +template +auto MapResult(void (Derived::Call::*fn)(ServerMetadata&, Derived*), Promise x, + FilterCallData* call_data) { + GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata); + return Map(std::move(x), [call_data](ServerMetadataHandle md) { + call_data->call.OnServerTrailingMetadata(*md, call_data->channel); + return md; + }); +} + template struct RunCallImpl; @@ -928,6 +938,19 @@ inline void InterceptServerTrailingMetadata( }); } +template +inline void InterceptServerTrailingMetadata( + void (Derived::Call::*fn)(ServerMetadata&, Derived*), + typename Derived::Call* call, Derived* channel, + CallSpineInterface* call_spine) { + GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata); + call_spine->server_trailing_metadata().sender.InterceptAndMap( + [call, channel](ServerMetadataHandle md) { + call->OnServerTrailingMetadata(*md, channel); + return md; + }); +} + template inline void InterceptServerTrailingMetadata( absl::Status (Derived::Call::*fn)(ServerMetadata&), @@ -941,11 +964,11 @@ inline void InterceptServerTrailingMetadata( }); } -inline void InterceptFinalize(const NoInterceptor*, void*) {} +inline void InterceptFinalize(const NoInterceptor*, void*, void*) {} template inline void InterceptFinalize(void (Call::*fn)(const grpc_call_final_info*), - Call* call) { + void*, Call* call) { GPR_DEBUG_ASSERT(fn == &Call::OnFinalize); GetContext()->Add( [call](const grpc_call_final_info* final_info) { @@ -953,6 +976,17 @@ inline void InterceptFinalize(void (Call::*fn)(const grpc_call_final_info*), }); } +template +inline void InterceptFinalize( + void (Derived::Call::*fn)(const grpc_call_final_info*, Derived*), + Derived* channel, typename Derived::Call* call) { + GPR_DEBUG_ASSERT(fn == &Derived::Call::OnFinalize); + GetContext()->Add( + [call, channel](const grpc_call_final_info* final_info) { + call->OnFinalize(final_info, channel); + }); +} + template absl::enable_if_t>::value, FilterCallData*> @@ -1050,7 +1084,8 @@ class ImplementChannelFilter : public ChannelFilter { promise_filter_detail::InterceptServerTrailingMetadata( &Derived::Call::OnServerTrailingMetadata, call, static_cast(this), call_spine); - promise_filter_detail::InterceptFinalize(&Derived::Call::OnFinalize, call); + promise_filter_detail::InterceptFinalize(&Derived::Call::OnFinalize, + static_cast(this), call); } // Polyfill for the original promise scheme. @@ -1067,7 +1102,7 @@ class ImplementChannelFilter : public ChannelFilter { promise_filter_detail::InterceptServerToClientMessage( &Derived::Call::OnServerToClientMessage, call, call_args); promise_filter_detail::InterceptFinalize( - &Derived::Call::OnFinalize, + &Derived::Call::OnFinalize, static_cast(this), static_cast(&call->call)); return promise_filter_detail::MapResult( &Derived::Call::OnServerTrailingMetadata, From 55b74dbe55e0ae56ea79d923303afb00f47c879e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Jan 2024 14:29:51 -0800 Subject: [PATCH 26/27] [call-v3] Convert `GrpcServerAuthzFilter` (#35472) Closes #35472 COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35472 from ctiller:gsaf 630b5514a7ec6f291aa2406af5632c53df15b17d PiperOrigin-RevId: 597045999 --- .../authorization/grpc_server_authz_filter.cc | 23 +++++++++++-------- .../authorization/grpc_server_authz_filter.h | 17 ++++++++++---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/core/lib/security/authorization/grpc_server_authz_filter.cc b/src/core/lib/security/authorization/grpc_server_authz_filter.cc index 8de911b5469..8e7f4fa3977 100644 --- a/src/core/lib/security/authorization/grpc_server_authz_filter.cc +++ b/src/core/lib/security/authorization/grpc_server_authz_filter.cc @@ -39,6 +39,12 @@ namespace grpc_core { TraceFlag grpc_authz_trace(false, "grpc_authz_api"); +const NoInterceptor GrpcServerAuthzFilter::Call::OnServerInitialMetadata; +const NoInterceptor GrpcServerAuthzFilter::Call::OnServerTrailingMetadata; +const NoInterceptor GrpcServerAuthzFilter::Call::OnClientToServerMessage; +const NoInterceptor GrpcServerAuthzFilter::Call::OnServerToClientMessage; +const NoInterceptor GrpcServerAuthzFilter::Call::OnFinalize; + GrpcServerAuthzFilter::GrpcServerAuthzFilter( RefCountedPtr auth_context, grpc_endpoint* endpoint, RefCountedPtr provider) @@ -61,9 +67,8 @@ absl::StatusOr GrpcServerAuthzFilter::Create( /*endpoint=*/nullptr, provider->Ref()); } -bool GrpcServerAuthzFilter::IsAuthorized( - const ClientMetadataHandle& initial_metadata) { - EvaluateArgs args(initial_metadata.get(), &per_channel_evaluate_args_); +bool GrpcServerAuthzFilter::IsAuthorized(ClientMetadata& initial_metadata) { + EvaluateArgs args(&initial_metadata, &per_channel_evaluate_args_); if (GRPC_TRACE_FLAG_ENABLED(grpc_authz_trace)) { gpr_log(GPR_DEBUG, "checking request: url_path=%s, transport_security_type=%s, " @@ -105,14 +110,12 @@ bool GrpcServerAuthzFilter::IsAuthorized( return false; } -ArenaPromise GrpcServerAuthzFilter::MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) { - if (!IsAuthorized(call_args.client_initial_metadata)) { - return ArenaPromise( - Immediate(ServerMetadataFromStatus(absl::PermissionDeniedError( - "Unauthorized RPC request rejected.")))); +absl::Status GrpcServerAuthzFilter::Call::OnClientInitialMetadata( + ClientMetadata& md, GrpcServerAuthzFilter* filter) { + if (!filter->IsAuthorized(md)) { + return absl::PermissionDeniedError("Unauthorized RPC request rejected."); } - return next_promise_factory(std::move(call_args)); + return absl::OkStatus(); } const grpc_channel_filter GrpcServerAuthzFilter::kFilterVtable = diff --git a/src/core/lib/security/authorization/grpc_server_authz_filter.h b/src/core/lib/security/authorization/grpc_server_authz_filter.h index a26db877082..e4727f1f789 100644 --- a/src/core/lib/security/authorization/grpc_server_authz_filter.h +++ b/src/core/lib/security/authorization/grpc_server_authz_filter.h @@ -34,22 +34,31 @@ namespace grpc_core { -class GrpcServerAuthzFilter final : public ChannelFilter { +class GrpcServerAuthzFilter final + : public ImplementChannelFilter { public: static const grpc_channel_filter kFilterVtable; static absl::StatusOr Create(const ChannelArgs& args, ChannelFilter::Args); - ArenaPromise MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) override; + class Call { + public: + absl::Status OnClientInitialMetadata(ClientMetadata& md, + GrpcServerAuthzFilter* filter); + static const NoInterceptor OnServerInitialMetadata; + static const NoInterceptor OnServerTrailingMetadata; + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + static const NoInterceptor OnFinalize; + }; private: GrpcServerAuthzFilter( RefCountedPtr auth_context, grpc_endpoint* endpoint, RefCountedPtr provider); - bool IsAuthorized(const ClientMetadataHandle& initial_metadata); + bool IsAuthorized(ClientMetadata& initial_metadata); RefCountedPtr auth_context_; EvaluateArgs::PerChannelArgs per_channel_evaluate_args_; From 20e5b2c4bb1f52221b8234176a46e90f50bb4cec Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 9 Jan 2024 15:38:55 -0800 Subject: [PATCH 27/27] [xDS] read connection idle timeout from CDS resource (#35395) Part of the work needed for in-progress gRFC A75 (https://github.com/grpc/proposal/pull/405). Closes #35395 PiperOrigin-RevId: 597064473 --- BUILD | 10 + CMakeLists.txt | 13 + Makefile | 4 + Package.swift | 5 + build_autogenerated.yaml | 7 + config.m4 | 4 + config.w32 | 8 + gRPC-C++.podspec | 6 + gRPC-Core.podspec | 8 + grpc.gemspec | 5 + grpc.gyp | 2 + package.xml | 5 + src/core/BUILD | 12 + .../http/v3/http_protocol_options.upb.h | 712 ++++++++++++++++++ .../v3/http_protocol_options.upb_minitable.c | 151 ++++ .../v3/http_protocol_options.upb_minitable.h | 33 + .../http/v3/http_protocol_options.upbdefs.c | 133 ++++ .../http/v3/http_protocol_options.upbdefs.h | 50 ++ src/core/ext/xds/xds_cluster.cc | 58 ++ src/core/ext/xds/xds_cluster.h | 6 + src/proto/grpc/testing/xds/v3/BUILD | 10 + src/proto/grpc/testing/xds/v3/cluster.proto | 2 + .../xds/v3/http_protocol_options.proto | 26 + src/proto/grpc/testing/xds/v3/protocol.proto | 5 +- src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/xds/BUILD | 1 + .../xds/xds_cluster_resource_type_test.cc | 204 +++++ tools/doxygen/Doxyfile.c++.internal | 5 + tools/doxygen/Doxyfile.core.internal | 5 + 29 files changed, 1491 insertions(+), 1 deletion(-) create mode 100644 src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h create mode 100644 src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c create mode 100644 src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h create mode 100644 src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c create mode 100644 src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h create mode 100644 src/proto/grpc/testing/xds/v3/http_protocol_options.proto diff --git a/BUILD b/BUILD index e244afae282..feb7d315176 100644 --- a/BUILD +++ b/BUILD @@ -4304,6 +4304,16 @@ grpc_upb_proto_reflection_library( deps = ["@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg"], ) +grpc_upb_proto_library( + name = "envoy_extensions_upstreams_http_upb", + deps = ["@envoy_api//envoy/extensions/upstreams/http/v3:pkg"], +) + +grpc_upb_proto_reflection_library( + name = "envoy_extensions_upstreams_http_upbdefs", + deps = ["@envoy_api//envoy/extensions/upstreams/http/v3:pkg"], +) + grpc_upb_proto_library( name = "envoy_service_discovery_upb", deps = ["@envoy_api//envoy/service/discovery/v3:pkg"], diff --git a/CMakeLists.txt b/CMakeLists.txt index bd67b71673e..4455b799b10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -738,6 +738,9 @@ protobuf_generate_grpc_cpp_with_import_path_correction( protobuf_generate_grpc_cpp_with_import_path_correction( src/proto/grpc/testing/xds/v3/http_filter_rbac.proto src/proto/grpc/testing/xds/v3/http_filter_rbac.proto ) +protobuf_generate_grpc_cpp_with_import_path_correction( + src/proto/grpc/testing/xds/v3/http_protocol_options.proto src/proto/grpc/testing/xds/v3/http_protocol_options.proto +) protobuf_generate_grpc_cpp_with_import_path_correction( src/proto/grpc/testing/xds/v3/listener.proto src/proto/grpc/testing/xds/v3/listener.proto ) @@ -1951,6 +1954,7 @@ add_library(grpc src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c + src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c @@ -2109,6 +2113,7 @@ add_library(grpc src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c + src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c @@ -27107,6 +27112,10 @@ add_executable(xds_cluster_resource_type_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_protocol_options.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_protocol_options.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_protocol_options.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_protocol_options.grpc.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.pb.h @@ -27115,6 +27124,10 @@ add_executable(xds_cluster_resource_type_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.pb.h diff --git a/Makefile b/Makefile index 6b741178ac3..1d547978b3d 100644 --- a/Makefile +++ b/Makefile @@ -1155,6 +1155,7 @@ LIBGRPC_SRC = \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c \ + src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c \ @@ -1313,6 +1314,7 @@ LIBGRPC_SRC = \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c \ + src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c \ @@ -3471,6 +3473,7 @@ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb_minita src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c: $(OPENSSL_DEP) src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c: $(OPENSSL_DEP) src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c: $(OPENSSL_DEP) +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c: $(OPENSSL_DEP) src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c: $(OPENSSL_DEP) src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c: $(OPENSSL_DEP) src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c: $(OPENSSL_DEP) @@ -3610,6 +3613,7 @@ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdef src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c: $(OPENSSL_DEP) +src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c: $(OPENSSL_DEP) diff --git a/Package.swift b/Package.swift index 45407ba6dbc..909c493af11 100644 --- a/Package.swift +++ b/Package.swift @@ -586,6 +586,9 @@ let package = Package( "src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h", "src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c", "src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h", + "src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h", + "src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c", + "src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h", "src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h", "src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c", "src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h", @@ -983,6 +986,8 @@ let package = Package( "src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h", "src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c", "src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h", + "src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c", + "src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h", "src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c", "src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h", "src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index f3ca12108f4..bc7c267efdd 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -488,6 +488,8 @@ libs: - src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.h - src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h - src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h + - src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h + - src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h - src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h - src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h - src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb.h @@ -727,6 +729,7 @@ libs: - src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h - src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h - src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h + - src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h - src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h - src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.h - src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.h @@ -1415,6 +1418,7 @@ libs: - src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c - src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c - src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c + - src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c - src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c - src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c - src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c @@ -1573,6 +1577,7 @@ libs: - src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c - src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c - src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c + - src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c - src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c - src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c - src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c @@ -18073,8 +18078,10 @@ targets: - src/proto/grpc/testing/xds/v3/endpoint.proto - src/proto/grpc/testing/xds/v3/extension.proto - src/proto/grpc/testing/xds/v3/health_check.proto + - src/proto/grpc/testing/xds/v3/http_protocol_options.proto - src/proto/grpc/testing/xds/v3/outlier_detection.proto - src/proto/grpc/testing/xds/v3/percent.proto + - src/proto/grpc/testing/xds/v3/protocol.proto - src/proto/grpc/testing/xds/v3/regex.proto - src/proto/grpc/testing/xds/v3/round_robin.proto - src/proto/grpc/testing/xds/v3/string.proto diff --git a/config.m4 b/config.m4 index a0d3549d7f0..eaafbe168f0 100644 --- a/config.m4 +++ b/config.m4 @@ -241,6 +241,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c \ + src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c \ @@ -399,6 +400,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c \ + src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c \ @@ -1425,6 +1427,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/ring_hash/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/wrr_locality/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/service/discovery/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/service/load_stats/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/service/status/v3) @@ -1475,6 +1478,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/http/stateful_session/cookie/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/service/discovery/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/service/load_stats/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/service/status/v3) diff --git a/config.w32 b/config.w32 index ea2a72452f0..787f9184edd 100644 --- a/config.w32 +++ b/config.w32 @@ -206,6 +206,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\upb-gen\\envoy\\extensions\\transport_sockets\\tls\\v3\\secret.upb_minitable.c " + "src\\core\\ext\\upb-gen\\envoy\\extensions\\transport_sockets\\tls\\v3\\tls.upb_minitable.c " + "src\\core\\ext\\upb-gen\\envoy\\extensions\\transport_sockets\\tls\\v3\\tls_spiffe_validator_config.upb_minitable.c " + + "src\\core\\ext\\upb-gen\\envoy\\extensions\\upstreams\\http\\v3\\http_protocol_options.upb_minitable.c " + "src\\core\\ext\\upb-gen\\envoy\\service\\discovery\\v3\\ads.upb_minitable.c " + "src\\core\\ext\\upb-gen\\envoy\\service\\discovery\\v3\\discovery.upb_minitable.c " + "src\\core\\ext\\upb-gen\\envoy\\service\\load_stats\\v3\\lrs.upb_minitable.c " + @@ -364,6 +365,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\transport_sockets\\tls\\v3\\secret.upbdefs.c " + "src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\transport_sockets\\tls\\v3\\tls.upbdefs.c " + "src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\transport_sockets\\tls\\v3\\tls_spiffe_validator_config.upbdefs.c " + + "src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\upstreams\\http\\v3\\http_protocol_options.upbdefs.c " + "src\\core\\ext\\upbdefs-gen\\envoy\\service\\discovery\\v3\\ads.upbdefs.c " + "src\\core\\ext\\upbdefs-gen\\envoy\\service\\discovery\\v3\\discovery.upbdefs.c " + "src\\core\\ext\\upbdefs-gen\\envoy\\service\\load_stats\\v3\\lrs.upbdefs.c " + @@ -1465,6 +1467,9 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\extensions\\transport_sockets"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\extensions\\transport_sockets\\tls"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\extensions\\transport_sockets\\tls\\v3"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\extensions\\upstreams"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\extensions\\upstreams\\http"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\extensions\\upstreams\\http\\v3"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\service"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\service\\discovery"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-gen\\envoy\\service\\discovery\\v3"); @@ -1583,6 +1588,9 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\transport_sockets"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\transport_sockets\\tls"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\transport_sockets\\tls\\v3"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\upstreams"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\upstreams\\http"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\extensions\\upstreams\\http\\v3"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\service"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\service\\discovery"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-gen\\envoy\\service\\discovery\\v3"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a3592151f05..3cae944ab45 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -557,6 +557,8 @@ Pod::Spec.new do |s| 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb.h', @@ -796,6 +798,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.h', @@ -1799,6 +1802,8 @@ Pod::Spec.new do |s| 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb.h', @@ -2038,6 +2043,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 259a7473601..64a9a422c20 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -689,6 +689,9 @@ Pod::Spec.new do |s| 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h', @@ -1086,6 +1089,8 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c', @@ -2567,6 +2572,8 @@ Pod::Spec.new do |s| 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h', 'src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb.h', @@ -2806,6 +2813,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.h', 'src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.h', diff --git a/grpc.gemspec b/grpc.gemspec index 18146192284..7c770a8a534 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -592,6 +592,9 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h ) s.files += %w( src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c ) s.files += %w( src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h ) + s.files += %w( src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h ) + s.files += %w( src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c ) + s.files += %w( src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h ) s.files += %w( src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h ) s.files += %w( src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c ) s.files += %w( src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h ) @@ -989,6 +992,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c ) s.files += %w( src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h ) + s.files += %w( src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c ) + s.files += %w( src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c ) s.files += %w( src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c ) diff --git a/grpc.gyp b/grpc.gyp index e87ec7dcba8..37f7bb50dd0 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -474,6 +474,7 @@ 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c', @@ -632,6 +633,7 @@ 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c', diff --git a/package.xml b/package.xml index 436443d9097..9df45c5f2ea 100644 --- a/package.xml +++ b/package.xml @@ -574,6 +574,9 @@ + + + @@ -971,6 +974,8 @@ + + diff --git a/src/core/BUILD b/src/core/BUILD index d76984d9a33..f19a5b60cac 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -4521,6 +4521,8 @@ grpc_cc_library( "envoy_extensions_load_balancing_policies_wrr_locality_upb", "envoy_extensions_transport_sockets_tls_upb", "envoy_extensions_transport_sockets_tls_upbdefs", + "envoy_extensions_upstreams_http_upb", + "envoy_extensions_upstreams_http_upbdefs", "envoy_service_discovery_upb", "envoy_service_discovery_upbdefs", "envoy_service_load_stats_upb", @@ -6691,6 +6693,16 @@ grpc_upb_proto_reflection_library( deps = ["@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg"], ) +grpc_upb_proto_library( + name = "envoy_extensions_upstreams_http_upb", + deps = ["@envoy_api//envoy/extensions/upstreams/http/v3:pkg"], +) + +grpc_upb_proto_reflection_library( + name = "envoy_extensions_upstreams_http_upbdefs", + deps = ["@envoy_api//envoy/extensions/upstreams/http/v3:pkg"], +) + grpc_upb_proto_library( name = "envoy_service_discovery_upb", deps = ["@envoy_api//envoy/service/discovery/v3:pkg"], diff --git a/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h b/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h new file mode 100644 index 00000000000..7f4e66d53f3 --- /dev/null +++ b/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h @@ -0,0 +1,712 @@ +/* This file was generated by upb_generator from the input file: + * + * envoy/extensions/upstreams/http/v3/http_protocol_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPB_H_ +#define ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPB_H_ + +#include "upb/generated_code_support.h" + +#include "envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h" + +#include "envoy/config/core/v3/extension.upb_minitable.h" +#include "envoy/config/core/v3/protocol.upb_minitable.h" +#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.h" +#include "udpa/annotations/status.upb_minitable.h" +#include "validate/validate.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions envoy_extensions_upstreams_http_v3_HttpProtocolOptions; +typedef struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig; +typedef struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig; +typedef struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig; +struct envoy_config_core_v3_AlternateProtocolsCacheOptions; +struct envoy_config_core_v3_Http1ProtocolOptions; +struct envoy_config_core_v3_Http2ProtocolOptions; +struct envoy_config_core_v3_Http3ProtocolOptions; +struct envoy_config_core_v3_HttpProtocolOptions; +struct envoy_config_core_v3_TypedExtensionConfig; +struct envoy_config_core_v3_UpstreamHttpProtocolOptions; +struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter; + + + +/* envoy.extensions.upstreams.http.v3.HttpProtocolOptions */ + +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_new(upb_Arena* arena) { + return (envoy_extensions_upstreams_http_v3_HttpProtocolOptions*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init, arena); +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_parse(const char* buf, size_t size, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_serialize(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_serialize_ex(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +typedef enum { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_explicit_http_config = 3, + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_use_downstream_protocol_config = 4, + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_auto_config = 5, + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_NOT_SET = 0 +} envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_oneofcases; +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_oneofcases envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_case(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_protocol_options_oneofcases)upb_Message_WhichOneofFieldNumber(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_common_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_HttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_common_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const struct envoy_config_core_v3_HttpProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_HttpProtocolOptions* ret; + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_common_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_upstream_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_UpstreamHttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const struct envoy_config_core_v3_UpstreamHttpProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_UpstreamHttpProtocolOptions* ret; + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_upstream_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_explicit_http_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_explicit_http_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* default_val = NULL; + const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* ret; + const upb_MiniTableField field = {3, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_explicit_http_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_use_downstream_protocol_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_use_downstream_protocol_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* default_val = NULL; + const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* ret; + const upb_MiniTableField field = {4, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_use_downstream_protocol_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_auto_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_auto_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* default_val = NULL; + const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* ret; + const upb_MiniTableField field = {5, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_auto_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_http_filters(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_http_filters(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(msg, &field); + if (arr) { + if (size) *size = arr->size; + return (const struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const*)_upb_array_constptr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _envoy_extensions_upstreams_http_v3_HttpProtocolOptions_http_filters_upb_array(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(msg, &field); + if (size) { + *size = arr ? arr->size : 0; + } + return arr; +} +UPB_INLINE upb_Array* _envoy_extensions_upstreams_http_v3_HttpProtocolOptions_http_filters_mutable_upb_array(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + (upb_Message*)msg, &field, arena); + if (size) { + *size = arr ? arr->size : 0; + } + return arr; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_http_filters(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + size_t size; + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_http_filters(msg, &size); + return size != 0; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_clear_header_validation_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 32), 3, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_header_validation_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const struct envoy_config_core_v3_TypedExtensionConfig* default_val = NULL; + const struct envoy_config_core_v3_TypedExtensionConfig* ret; + const upb_MiniTableField field = {7, UPB_SIZE(20, 32), 3, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_has_header_validation_config(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 32), 3, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} + +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_common_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions *msg, struct envoy_config_core_v3_HttpProtocolOptions* value) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_HttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_common_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + struct envoy_config_core_v3_HttpProtocolOptions* sub = (struct envoy_config_core_v3_HttpProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_common_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_HttpProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__HttpProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_common_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_upstream_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions *msg, struct envoy_config_core_v3_UpstreamHttpProtocolOptions* value) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_UpstreamHttpProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_upstream_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + struct envoy_config_core_v3_UpstreamHttpProtocolOptions* sub = (struct envoy_config_core_v3_UpstreamHttpProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_upstream_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_UpstreamHttpProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__UpstreamHttpProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_upstream_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_explicit_http_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions *msg, envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* value) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_explicit_http_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* sub = (struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_explicit_http_config(msg); + if (sub == NULL) { + sub = (struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_explicit_http_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_use_downstream_protocol_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions *msg, envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* value) { + const upb_MiniTableField field = {4, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_use_downstream_protocol_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* sub = (struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_use_downstream_protocol_config(msg); + if (sub == NULL) { + sub = (struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_use_downstream_protocol_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_auto_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions *msg, envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* value) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_auto_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* sub = (struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_auto_config(msg); + if (sub == NULL) { + sub = (struct envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_auto_config(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter** envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_http_filters(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(msg, &field); + if (arr) { + if (size) *size = arr->size; + return (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_ptr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter** envoy_extensions_upstreams_http_v3_HttpProtocolOptions_resize_http_filters(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)upb_Message_ResizeArrayUninitialized(msg, &field, size, arena); +} +UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_add_http_filters(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(msg, &field, arena); + if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { + return NULL; + } + struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter*)_upb_Message_New(&envoy__extensions__filters__network__http_0connection_0manager__v3__HttpFilter_msg_init, arena); + if (!arr || !sub) return NULL; + _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_header_validation_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions *msg, struct envoy_config_core_v3_TypedExtensionConfig* value) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 32), 3, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_mutable_header_validation_config(envoy_extensions_upstreams_http_v3_HttpProtocolOptions* msg, upb_Arena* arena) { + struct envoy_config_core_v3_TypedExtensionConfig* sub = (struct envoy_config_core_v3_TypedExtensionConfig*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_header_validation_config(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_TypedExtensionConfig*)_upb_Message_New(&envoy__config__core__v3__TypedExtensionConfig_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_set_header_validation_config(msg, sub); + } + return sub; +} + +/* envoy.extensions.upstreams.http.v3.HttpProtocolOptions.ExplicitHttpConfig */ + +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_new(upb_Arena* arena) { + return (envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, arena); +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_parse(const char* buf, size_t size, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_serialize(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_serialize_ex(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, options, arena, &ptr, len); + return ptr; +} +typedef enum { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_http_protocol_options = 1, + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_http2_protocol_options = 2, + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_http3_protocol_options = 3, + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_NOT_SET = 0 +} envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_oneofcases; +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_oneofcases envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_case(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), -1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_protocol_config_oneofcases)upb_Message_WhichOneofFieldNumber(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_clear_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), -1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const struct envoy_config_core_v3_Http1ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http1ProtocolOptions* ret; + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), -1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_has_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), -1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_clear_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(4, 8), -1, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_http2_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const struct envoy_config_core_v3_Http2ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http2ProtocolOptions* ret; + const upb_MiniTableField field = {2, UPB_SIZE(4, 8), -1, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_has_http2_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(4, 8), -1, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_clear_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(4, 8), -1, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http3ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_http3_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const struct envoy_config_core_v3_Http3ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http3ProtocolOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(4, 8), -1, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_has_http3_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(4, 8), -1, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} + +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_set_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig *msg, struct envoy_config_core_v3_Http1ProtocolOptions* value) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), -1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_mutable_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http1ProtocolOptions* sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http1ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_set_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_set_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig *msg, struct envoy_config_core_v3_Http2ProtocolOptions* value) { + const upb_MiniTableField field = {2, UPB_SIZE(4, 8), -1, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_mutable_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http2ProtocolOptions* sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http2ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_set_http2_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_set_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig *msg, struct envoy_config_core_v3_Http3ProtocolOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(4, 8), -1, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http3ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_mutable_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http3ProtocolOptions* sub = (struct envoy_config_core_v3_Http3ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_http3_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http3ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http3ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_set_http3_protocol_options(msg, sub); + } + return sub; +} + +/* envoy.extensions.upstreams.http.v3.HttpProtocolOptions.UseDownstreamHttpConfig */ + +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_new(upb_Arena* arena) { + return (envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, arena); +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_parse(const char* buf, size_t size, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_serialize(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_serialize_ex(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_clear_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const struct envoy_config_core_v3_Http1ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http1ProtocolOptions* ret; + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_has_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_clear_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_http2_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const struct envoy_config_core_v3_Http2ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http2ProtocolOptions* ret; + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_has_http2_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_clear_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http3ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_http3_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const struct envoy_config_core_v3_Http3ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http3ProtocolOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_has_http3_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} + +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_set_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig *msg, struct envoy_config_core_v3_Http1ProtocolOptions* value) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_mutable_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http1ProtocolOptions* sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http1ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_set_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_set_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig *msg, struct envoy_config_core_v3_Http2ProtocolOptions* value) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_mutable_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http2ProtocolOptions* sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http2ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_set_http2_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_set_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig *msg, struct envoy_config_core_v3_Http3ProtocolOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http3ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_mutable_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http3ProtocolOptions* sub = (struct envoy_config_core_v3_Http3ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_http3_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http3ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http3ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_set_http3_protocol_options(msg, sub); + } + return sub; +} + +/* envoy.extensions.upstreams.http.v3.HttpProtocolOptions.AutoHttpConfig */ + +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_new(upb_Arena* arena) { + return (envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig*)_upb_Message_New(&envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, arena); +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_parse(const char* buf, size_t size, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* ret = envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, ret, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, extreg, options, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_serialize(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_serialize_ex(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(msg, &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_clear_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const struct envoy_config_core_v3_Http1ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http1ProtocolOptions* ret; + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_has_http_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_clear_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_http2_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const struct envoy_config_core_v3_Http2ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http2ProtocolOptions* ret; + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_has_http2_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_clear_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_Http3ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_http3_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const struct envoy_config_core_v3_Http3ProtocolOptions* default_val = NULL; + const struct envoy_config_core_v3_Http3ProtocolOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_has_http3_protocol_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_clear_alternate_protocols_cache_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 32), 4, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const struct envoy_config_core_v3_AlternateProtocolsCacheOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_alternate_protocols_cache_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const struct envoy_config_core_v3_AlternateProtocolsCacheOptions* default_val = NULL; + const struct envoy_config_core_v3_AlternateProtocolsCacheOptions* ret; + const upb_MiniTableField field = {4, UPB_SIZE(16, 32), 4, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_has_alternate_protocols_cache_options(const envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 32), 4, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} + +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig *msg, struct envoy_config_core_v3_Http1ProtocolOptions* value) { + const upb_MiniTableField field = {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_mutable_http_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http1ProtocolOptions* sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http1ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig *msg, struct envoy_config_core_v3_Http2ProtocolOptions* value) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_mutable_http2_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http2ProtocolOptions* sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http2ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_http2_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig *msg, struct envoy_config_core_v3_Http3ProtocolOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_Http3ProtocolOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_mutable_http3_protocol_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_Http3ProtocolOptions* sub = (struct envoy_config_core_v3_Http3ProtocolOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_http3_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_Http3ProtocolOptions*)_upb_Message_New(&envoy__config__core__v3__Http3ProtocolOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_http3_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_alternate_protocols_cache_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig *msg, struct envoy_config_core_v3_AlternateProtocolsCacheOptions* value) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 32), 4, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE struct envoy_config_core_v3_AlternateProtocolsCacheOptions* envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_mutable_alternate_protocols_cache_options(envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig* msg, upb_Arena* arena) { + struct envoy_config_core_v3_AlternateProtocolsCacheOptions* sub = (struct envoy_config_core_v3_AlternateProtocolsCacheOptions*)envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_alternate_protocols_cache_options(msg); + if (sub == NULL) { + sub = (struct envoy_config_core_v3_AlternateProtocolsCacheOptions*)_upb_Message_New(&envoy__config__core__v3__AlternateProtocolsCacheOptions_msg_init, arena); + if (sub) envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_set_alternate_protocols_cache_options(msg, sub); + } + return sub; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c b/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c new file mode 100644 index 00000000000..e4909a1cf95 --- /dev/null +++ b/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c @@ -0,0 +1,151 @@ +/* This file was generated by upb_generator from the input file: + * + * envoy/extensions/upstreams/http/v3/http_protocol_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/generated_code_support.h" +#include "envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h" +#include "envoy/config/core/v3/extension.upb_minitable.h" +#include "envoy/config/core/v3/protocol.upb_minitable.h" +#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.h" +#include "udpa/annotations/status.upb_minitable.h" +#include "validate/validate.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +static const upb_MiniTableSub envoy_extensions_upstreams_http_v3_HttpProtocolOptions_submsgs[7] = { + {.submsg = &envoy__config__core__v3__HttpProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__UpstreamHttpProtocolOptions_msg_init}, + {.submsg = &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init}, + {.submsg = &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init}, + {.submsg = &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init}, + {.submsg = &envoy__extensions__filters__network__http_0connection_0manager__v3__HttpFilter_msg_init}, + {.submsg = &envoy__config__core__v3__TypedExtensionConfig_msg_init}, +}; + +static const upb_MiniTableField envoy_extensions_upstreams_http_v3_HttpProtocolOptions__fields[7] = { + {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 40), UPB_SIZE(-13, -5), 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(16, 24), 0, 5, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(20, 32), 3, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init = { + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_submsgs[0], + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions__fields[0], + UPB_SIZE(32, 48), 7, kUpb_ExtMode_NonExtendable, 7, UPB_FASTTABLE_MASK(56), 0, + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800000100000a, &upb_psm_1bt_maxmaxb}, + {0x0010000002010012, &upb_psm_1bt_maxmaxb}, + {0x002800040302001a, &upb_pom_1bt_max64b}, + {0x0028000404030022, &upb_pom_1bt_max64b}, + {0x002800040504002a, &upb_pom_1bt_max64b}, + {0x001800003f050032, &upb_prm_1bt_maxmaxb}, + {0x002000000306003a, &upb_psm_1bt_maxmaxb}, + }) +}; + +static const upb_MiniTableSub envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_submsgs[3] = { + {.submsg = &envoy__config__core__v3__Http1ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__Http2ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__Http3ProtocolOptions_msg_init}, +}; + +static const upb_MiniTableField envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig__fields[3] = { + {1, UPB_SIZE(4, 8), -1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(4, 8), -1, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(4, 8), -1, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init = { + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_submsgs[0], + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig__fields[0], + UPB_SIZE(8, 16), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800000100000a, &upb_pom_1bt_maxmaxb}, + {0x0008000002010012, &upb_pom_1bt_maxmaxb}, + {0x000800000302001a, &upb_pom_1bt_maxmaxb}, + }) +}; + +static const upb_MiniTableSub envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_submsgs[3] = { + {.submsg = &envoy__config__core__v3__Http1ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__Http2ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__Http3ProtocolOptions_msg_init}, +}; + +static const upb_MiniTableField envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig__fields[3] = { + {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init = { + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_submsgs[0], + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig__fields[0], + UPB_SIZE(16, 32), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800000100000a, &upb_psm_1bt_maxmaxb}, + {0x0010000002010012, &upb_psm_1bt_maxmaxb}, + {0x001800000302001a, &upb_psm_1bt_maxmaxb}, + }) +}; + +static const upb_MiniTableSub envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_submsgs[4] = { + {.submsg = &envoy__config__core__v3__Http1ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__Http2ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__Http3ProtocolOptions_msg_init}, + {.submsg = &envoy__config__core__v3__AlternateProtocolsCacheOptions_msg_init}, +}; + +static const upb_MiniTableField envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig__fields[4] = { + {1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 24), 3, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 32), 4, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init = { + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_submsgs[0], + &envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig__fields[0], + UPB_SIZE(24, 40), 4, kUpb_ExtMode_NonExtendable, 4, UPB_FASTTABLE_MASK(56), 0, + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800000100000a, &upb_psm_1bt_maxmaxb}, + {0x0010000002010012, &upb_psm_1bt_maxmaxb}, + {0x001800000302001a, &upb_psm_1bt_maxmaxb}, + {0x0020000004030022, &upb_psm_1bt_maxmaxb}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +static const upb_MiniTable *messages_layout[4] = { + &envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init, + &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init, + &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init, + &envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init, +}; + +const upb_MiniTableFile envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upb_file_layout = { + messages_layout, + NULL, + NULL, + 4, + 0, + 0, +}; + +#include "upb/port/undef.inc" + diff --git a/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h b/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h new file mode 100644 index 00000000000..c4bd8317c35 --- /dev/null +++ b/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h @@ -0,0 +1,33 @@ +/* This file was generated by upb_generator from the input file: + * + * envoy/extensions/upstreams/http/v3/http_protocol_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPB_MINITABLE_H_ +#define ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPB_MINITABLE_H_ + +#include "upb/generated_code_support.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions_msg_init; +extern const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions__ExplicitHttpConfig_msg_init; +extern const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions__UseDownstreamHttpConfig_msg_init; +extern const upb_MiniTable envoy__extensions__upstreams__http__v3__HttpProtocolOptions__AutoHttpConfig_msg_init; + +extern const upb_MiniTableFile envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPB_MINITABLE_H_ */ diff --git a/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c b/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c new file mode 100644 index 00000000000..1f40ce54ae4 --- /dev/null +++ b/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c @@ -0,0 +1,133 @@ +/* This file was generated by upb_generator from the input file: + * + * envoy/extensions/upstreams/http/v3/http_protocol_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "upb/reflection/def.h" +#include "envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h" +#include "envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h" + +extern _upb_DefPool_Init envoy_config_core_v3_extension_proto_upbdefinit; +extern _upb_DefPool_Init envoy_config_core_v3_protocol_proto_upbdefinit; +extern _upb_DefPool_Init envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_upbdefinit; +extern _upb_DefPool_Init udpa_annotations_status_proto_upbdefinit; +extern _upb_DefPool_Init validate_validate_proto_upbdefinit; +static const char descriptor[2490] = {'\n', '>', 'e', 'n', 'v', 'o', 'y', '/', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '/', 'u', 'p', 's', 't', 'r', 'e', +'a', 'm', 's', '/', 'h', 't', 't', 'p', '/', 'v', '3', '/', 'h', 't', 't', 'p', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', +'_', 'o', 'p', 't', 'i', 'o', 'n', 's', '.', 'p', 'r', 'o', 't', 'o', '\022', '\"', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', +'e', 'n', 's', 'i', 'o', 'n', 's', '.', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', 's', '.', 'h', 't', 't', 'p', '.', 'v', '3', +'\032', '$', 'e', 'n', 'v', 'o', 'y', '/', 'c', 'o', 'n', 'f', 'i', 'g', '/', 'c', 'o', 'r', 'e', '/', 'v', '3', '/', 'e', 'x', +'t', 'e', 'n', 's', 'i', 'o', 'n', '.', 'p', 'r', 'o', 't', 'o', '\032', '#', 'e', 'n', 'v', 'o', 'y', '/', 'c', 'o', 'n', 'f', +'i', 'g', '/', 'c', 'o', 'r', 'e', '/', 'v', '3', '/', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '.', 'p', 'r', 'o', 't', 'o', +'\032', 'Y', 'e', 'n', 'v', 'o', 'y', '/', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '/', 'f', 'i', 'l', 't', 'e', 'r', +'s', '/', 'n', 'e', 't', 'w', 'o', 'r', 'k', '/', 'h', 't', 't', 'p', '_', 'c', 'o', 'n', 'n', 'e', 'c', 't', 'i', 'o', 'n', +'_', 'm', 'a', 'n', 'a', 'g', 'e', 'r', '/', 'v', '3', '/', 'h', 't', 't', 'p', '_', 'c', 'o', 'n', 'n', 'e', 'c', 't', 'i', +'o', 'n', '_', 'm', 'a', 'n', 'a', 'g', 'e', 'r', '.', 'p', 'r', 'o', 't', 'o', '\032', '\035', 'u', 'd', 'p', 'a', '/', 'a', 'n', +'n', 'o', 't', 'a', 't', 'i', 'o', 'n', 's', '/', 's', 't', 'a', 't', 'u', 's', '.', 'p', 'r', 'o', 't', 'o', '\032', '\027', 'v', +'a', 'l', 'i', 'd', 'a', 't', 'e', '/', 'v', 'a', 'l', 'i', 'd', 'a', 't', 'e', '.', 'p', 'r', 'o', 't', 'o', '\"', '\302', '\017', +'\n', '\023', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'j', '\n', '\034', +'c', 'o', 'm', 'm', 'o', 'n', '_', 'h', 't', 't', 'p', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', +'o', 'n', 's', '\030', '\001', ' ', '\001', '(', '\013', '2', ')', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', +'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', +'n', 's', 'R', '\031', 'c', 'o', 'm', 'm', 'o', 'n', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', +'i', 'o', 'n', 's', '\022', 'v', '\n', '\036', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', '_', 'h', 't', 't', 'p', '_', 'p', 'r', 'o', +'t', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '1', '.', 'e', 'n', 'v', +'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'U', 'p', 's', 't', 'r', 'e', 'a', +'m', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\033', 'u', 'p', 's', +'t', 'r', 'e', 'a', 'm', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', +'~', '\n', '\024', 'e', 'x', 'p', 'l', 'i', 'c', 'i', 't', '_', 'h', 't', 't', 'p', '_', 'c', 'o', 'n', 'f', 'i', 'g', '\030', '\003', +' ', '\001', '(', '\013', '2', 'J', '.', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '.', 'u', +'p', 's', 't', 'r', 'e', 'a', 'm', 's', '.', 'h', 't', 't', 'p', '.', 'v', '3', '.', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', +'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'E', 'x', 'p', 'l', 'i', 'c', 'i', 't', 'H', 't', 't', 'p', 'C', +'o', 'n', 'f', 'i', 'g', 'H', '\000', 'R', '\022', 'e', 'x', 'p', 'l', 'i', 'c', 'i', 't', 'H', 't', 't', 'p', 'C', 'o', 'n', 'f', +'i', 'g', '\022', '\226', '\001', '\n', '\036', 'u', 's', 'e', '_', 'd', 'o', 'w', 'n', 's', 't', 'r', 'e', 'a', 'm', '_', 'p', 'r', 'o', +'t', 'o', 'c', 'o', 'l', '_', 'c', 'o', 'n', 'f', 'i', 'g', '\030', '\004', ' ', '\001', '(', '\013', '2', 'O', '.', 'e', 'n', 'v', 'o', +'y', '.', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '.', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', 's', '.', 'h', 't', +'t', 'p', '.', 'v', '3', '.', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', +'.', 'U', 's', 'e', 'D', 'o', 'w', 'n', 's', 't', 'r', 'e', 'a', 'm', 'H', 't', 't', 'p', 'C', 'o', 'n', 'f', 'i', 'g', 'H', +'\000', 'R', '\033', 'u', 's', 'e', 'D', 'o', 'w', 'n', 's', 't', 'r', 'e', 'a', 'm', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'C', +'o', 'n', 'f', 'i', 'g', '\022', 'i', '\n', '\013', 'a', 'u', 't', 'o', '_', 'c', 'o', 'n', 'f', 'i', 'g', '\030', '\005', ' ', '\001', '(', +'\013', '2', 'F', '.', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '.', 'u', 'p', 's', 't', +'r', 'e', 'a', 'm', 's', '.', 'h', 't', 't', 'p', '.', 'v', '3', '.', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', +'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'A', 'u', 't', 'o', 'H', 't', 't', 'p', 'C', 'o', 'n', 'f', 'i', 'g', 'H', '\000', +'R', '\n', 'a', 'u', 't', 'o', 'C', 'o', 'n', 'f', 'i', 'g', '\022', 'j', '\n', '\014', 'h', 't', 't', 'p', '_', 'f', 'i', 'l', 't', +'e', 'r', 's', '\030', '\006', ' ', '\003', '(', '\013', '2', 'G', '.', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', 'e', 'n', 's', 'i', +'o', 'n', 's', '.', 'f', 'i', 'l', 't', 'e', 'r', 's', '.', 'n', 'e', 't', 'w', 'o', 'r', 'k', '.', 'h', 't', 't', 'p', '_', +'c', 'o', 'n', 'n', 'e', 'c', 't', 'i', 'o', 'n', '_', 'm', 'a', 'n', 'a', 'g', 'e', 'r', '.', 'v', '3', '.', 'H', 't', 't', +'p', 'F', 'i', 'l', 't', 'e', 'r', 'R', '\013', 'h', 't', 't', 'p', 'F', 'i', 'l', 't', 'e', 'r', 's', '\022', 'd', '\n', '\030', 'h', +'e', 'a', 'd', 'e', 'r', '_', 'v', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '_', 'c', 'o', 'n', 'f', 'i', 'g', '\030', '\007', +' ', '\001', '(', '\013', '2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', +'v', '3', '.', 'T', 'y', 'p', 'e', 'd', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'C', 'o', 'n', 'f', 'i', 'g', 'R', '\026', +'h', 'e', 'a', 'd', 'e', 'r', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', 'C', 'o', 'n', 'f', 'i', 'g', '\032', '\326', '\002', +'\n', '\022', 'E', 'x', 'p', 'l', 'i', 'c', 'i', 't', 'H', 't', 't', 'p', 'C', 'o', 'n', 'f', 'i', 'g', '\022', '`', '\n', '\025', 'h', +'t', 't', 'p', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\001', ' ', '\001', '(', +'\013', '2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', +'H', 't', 't', 'p', '1', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'H', '\000', 'R', '\023', 'h', +'t', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'b', '\n', '\026', 'h', 't', 't', +'p', '2', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', +'2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', +'t', 't', 'p', '2', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'H', '\000', 'R', '\024', 'h', 't', +'t', 'p', '2', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'b', '\n', '\026', 'h', 't', 't', +'p', '3', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', +'2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', +'t', 't', 'p', '3', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'H', '\000', 'R', '\024', 'h', 't', +'t', 'p', '3', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'B', '\026', '\n', '\017', 'p', 'r', 'o', +'t', 'o', 'c', 'o', 'l', '_', 'c', 'o', 'n', 'f', 'i', 'g', '\022', '\003', '\370', 'B', '\001', '\032', '\275', '\002', '\n', '\027', 'U', 's', 'e', +'D', 'o', 'w', 'n', 's', 't', 'r', 'e', 'a', 'm', 'H', 't', 't', 'p', 'C', 'o', 'n', 'f', 'i', 'g', '\022', '^', '\n', '\025', 'h', +'t', 't', 'p', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\001', ' ', '\001', '(', +'\013', '2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', +'H', 't', 't', 'p', '1', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\023', 'h', 't', 't', +'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '`', '\n', '\026', 'h', 't', 't', 'p', '2', +'_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '*', +'.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', 't', 't', +'p', '2', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\024', 'h', 't', 't', 'p', '2', 'P', +'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '`', '\n', '\026', 'h', 't', 't', 'p', '3', '_', 'p', +'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '*', '.', 'e', +'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', 't', 't', 'p', '3', +'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\024', 'h', 't', 't', 'p', '3', 'P', 'r', 'o', +'t', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\032', '\265', '\003', '\n', '\016', 'A', 'u', 't', 'o', 'H', 't', 't', 'p', +'C', 'o', 'n', 'f', 'i', 'g', '\022', '^', '\n', '\025', 'h', 't', 't', 'p', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', +'p', 't', 'i', 'o', 'n', 's', '\030', '\001', ' ', '\001', '(', '\013', '2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', +'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', 't', 't', 'p', '1', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', +'p', 't', 'i', 'o', 'n', 's', 'R', '\023', 'h', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', +'n', 's', '\022', '`', '\n', '\026', 'h', 't', 't', 'p', '2', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', +'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', +'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'H', 't', 't', 'p', '2', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', +'o', 'n', 's', 'R', '\024', 'h', 't', 't', 'p', '2', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', +'\022', '`', '\n', '\026', 'h', 't', 't', 'p', '3', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', 'p', 't', 'i', 'o', 'n', +'s', '\030', '\003', ' ', '\001', '(', '\013', '2', '*', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', +'r', 'e', '.', 'v', '3', '.', 'H', 't', 't', 'p', '3', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', +'s', 'R', '\024', 'h', 't', 't', 'p', '3', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\177', +'\n', '!', 'a', 'l', 't', 'e', 'r', 'n', 'a', 't', 'e', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', 's', '_', 'c', 'a', 'c', +'h', 'e', '_', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013', '2', '4', '.', 'e', 'n', 'v', 'o', 'y', '.', +'c', 'o', 'n', 'f', 'i', 'g', '.', 'c', 'o', 'r', 'e', '.', 'v', '3', '.', 'A', 'l', 't', 'e', 'r', 'n', 'a', 't', 'e', 'P', +'r', 'o', 't', 'o', 'c', 'o', 'l', 's', 'C', 'a', 'c', 'h', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\036', 'a', 'l', 't', +'e', 'r', 'n', 'a', 't', 'e', 'P', 'r', 'o', 't', 'o', 'c', 'o', 'l', 's', 'C', 'a', 'c', 'h', 'e', 'O', 'p', 't', 'i', 'o', +'n', 's', 'B', ' ', '\n', '\031', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l', '_', 'o', +'p', 't', 'i', 'o', 'n', 's', '\022', '\003', '\370', 'B', '\001', 'B', '\250', '\001', '\n', '0', 'i', 'o', '.', 'e', 'n', 'v', 'o', 'y', 'p', +'r', 'o', 'x', 'y', '.', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '.', 'u', 'p', 's', +'t', 'r', 'e', 'a', 'm', 's', '.', 'h', 't', 't', 'p', '.', 'v', '3', 'B', '\030', 'H', 't', 't', 'p', 'P', 'r', 'o', 't', 'o', +'c', 'o', 'l', 'O', 'p', 't', 'i', 'o', 'n', 's', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', 'P', 'g', 'i', 't', 'h', 'u', 'b', +'.', 'c', 'o', 'm', '/', 'e', 'n', 'v', 'o', 'y', 'p', 'r', 'o', 'x', 'y', '/', 'g', 'o', '-', 'c', 'o', 'n', 't', 'r', 'o', +'l', '-', 'p', 'l', 'a', 'n', 'e', '/', 'e', 'n', 'v', 'o', 'y', '/', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '/', +'u', 'p', 's', 't', 'r', 'e', 'a', 'm', 's', '/', 'h', 't', 't', 'p', '/', 'v', '3', ';', 'h', 't', 't', 'p', 'v', '3', '\272', +'\200', '\310', '\321', '\006', '\002', '\020', '\002', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static _upb_DefPool_Init *deps[6] = { + &envoy_config_core_v3_extension_proto_upbdefinit, + &envoy_config_core_v3_protocol_proto_upbdefinit, + &envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_upbdefinit, + &udpa_annotations_status_proto_upbdefinit, + &validate_validate_proto_upbdefinit, + NULL +}; + +_upb_DefPool_Init envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upbdefinit = { + deps, + &envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upb_file_layout, + "envoy/extensions/upstreams/http/v3/http_protocol_options.proto", + UPB_STRINGVIEW_INIT(descriptor, 2490) +}; diff --git a/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h b/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h new file mode 100644 index 00000000000..9f2805d7578 --- /dev/null +++ b/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h @@ -0,0 +1,50 @@ +/* This file was generated by upb_generator from the input file: + * + * envoy/extensions/upstreams/http/v3/http_protocol_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPBDEFS_H_ +#define ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPBDEFS_H_ + +#include "upb/reflection/def.h" +#include "upb/reflection/internal/def_pool.h" +#include "upb/port/def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +#include "upb/reflection/def.h" + +#include "upb/port/def.inc" + +extern _upb_DefPool_Init envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upbdefinit; + +UPB_INLINE const upb_MessageDef *envoy_extensions_upstreams_http_v3_HttpProtocolOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "envoy.extensions.upstreams.http.v3.HttpProtocolOptions"); +} + +UPB_INLINE const upb_MessageDef *envoy_extensions_upstreams_http_v3_HttpProtocolOptions_ExplicitHttpConfig_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "envoy.extensions.upstreams.http.v3.HttpProtocolOptions.ExplicitHttpConfig"); +} + +UPB_INLINE const upb_MessageDef *envoy_extensions_upstreams_http_v3_HttpProtocolOptions_UseDownstreamHttpConfig_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "envoy.extensions.upstreams.http.v3.HttpProtocolOptions.UseDownstreamHttpConfig"); +} + +UPB_INLINE const upb_MessageDef *envoy_extensions_upstreams_http_v3_HttpProtocolOptions_AutoHttpConfig_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &envoy_extensions_upstreams_http_v3_http_protocol_options_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "envoy.extensions.upstreams.http.v3.HttpProtocolOptions.AutoHttpConfig"); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* ENVOY_EXTENSIONS_UPSTREAMS_HTTP_V3_HTTP_PROTOCOL_OPTIONS_PROTO_UPBDEFS_H_ */ diff --git a/src/core/ext/xds/xds_cluster.cc b/src/core/ext/xds/xds_cluster.cc index 2386a43a521..7edd3e8be3c 100644 --- a/src/core/ext/xds/xds_cluster.cc +++ b/src/core/ext/xds/xds_cluster.cc @@ -38,11 +38,14 @@ #include "envoy/config/core/v3/address.upb.h" #include "envoy/config/core/v3/base.upb.h" #include "envoy/config/core/v3/config_source.upb.h" +#include "envoy/config/core/v3/extension.upb.h" #include "envoy/config/core/v3/health_check.upb.h" +#include "envoy/config/core/v3/protocol.upb.h" #include "envoy/config/endpoint/v3/endpoint.upb.h" #include "envoy/config/endpoint/v3/endpoint_components.upb.h" #include "envoy/extensions/clusters/aggregate/v3/cluster.upb.h" #include "envoy/extensions/transport_sockets/tls/v3/tls.upb.h" +#include "envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h" #include "google/protobuf/any.upb.h" #include "google/protobuf/duration.upb.h" #include "google/protobuf/wrappers.upb.h" @@ -105,6 +108,10 @@ std::string XdsClusterResource::ToString() const { contents.push_back( absl::StrCat("common_tls_context=", common_tls_context.ToString())); } + if (connection_idle_timeout != Duration::Zero()) { + contents.push_back(absl::StrCat("connection_idle_timeout=", + connection_idle_timeout.ToString())); + } contents.push_back( absl::StrCat("max_concurrent_requests=", max_concurrent_requests)); contents.push_back(absl::StrCat("override_host_statuses=", @@ -400,6 +407,50 @@ void ParseLbPolicyConfig(const XdsResourceType::DecodeContext& context, } } +void ParseUpstreamConfig( + const XdsResourceType::DecodeContext& context, + const envoy_config_core_v3_TypedExtensionConfig* upstream_config, + XdsClusterResource* cds_update, ValidationErrors* errors) { + ValidationErrors::ScopedField field(errors, ".typed_config"); + const auto* typed_config = + envoy_config_core_v3_TypedExtensionConfig_typed_config(upstream_config); + auto extension = ExtractXdsExtension(context, typed_config, errors); + if (!extension.has_value()) return; + if (extension->type != + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions") { + ValidationErrors::ScopedField field(errors, ".type_url"); + errors->AddError("unsupported upstream config type"); + return; + } + absl::string_view* serialized_http_protocol_options = + absl::get_if(&extension->value); + if (serialized_http_protocol_options == nullptr) { + errors->AddError("can't decode HttpProtocolOptions"); + return; + } + const auto* http_protocol_options = + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_parse( + serialized_http_protocol_options->data(), + serialized_http_protocol_options->size(), context.arena); + if (http_protocol_options == nullptr) { + errors->AddError("can't decode HttpProtocolOptions"); + return; + } + ValidationErrors::ScopedField field2(errors, ".common_http_protocol_options"); + const auto* common_http_protocol_options = + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_common_http_protocol_options( + http_protocol_options); + if (common_http_protocol_options != nullptr) { + const auto* idle_timeout = + envoy_config_core_v3_HttpProtocolOptions_idle_timeout( + common_http_protocol_options); + if (idle_timeout != nullptr) { + ValidationErrors::ScopedField field(errors, ".idle_timeout"); + cds_update->connection_idle_timeout = ParseDuration(idle_timeout, errors); + } + } +} + absl::StatusOr> CdsResourceParse( const XdsResourceType::DecodeContext& context, const envoy_config_cluster_v3_Cluster* cluster) { @@ -467,6 +518,13 @@ absl::StatusOr> CdsResourceParse( cds_update->lrs_load_reporting_server.emplace( static_cast(context.server)); } + // Protocol options. + auto* upstream_config = + envoy_config_cluster_v3_Cluster_upstream_config(cluster); + if (upstream_config != nullptr) { + ValidationErrors::ScopedField field(&errors, ".upstream_config"); + ParseUpstreamConfig(context, upstream_config, cds_update.get(), &errors); + } // The Cluster resource encodes the circuit breaking parameters in a list of // Thresholds messages, where each message specifies the parameters for a // particular RoutingPriority. we will look only at the first entry in the diff --git a/src/core/ext/xds/xds_cluster.h b/src/core/ext/xds/xds_cluster.h index 4a4749b6bf3..f92cba623ee 100644 --- a/src/core/ext/xds/xds_cluster.h +++ b/src/core/ext/xds/xds_cluster.h @@ -31,6 +31,7 @@ #include "envoy/config/cluster/v3/cluster.upbdefs.h" #include "envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h" #include "envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h" +#include "envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h" #include "upb/reflection/def.h" #include @@ -89,6 +90,9 @@ struct XdsClusterResource : public XdsResourceType::ResourceData { // Tls Context used by clients CommonTlsContext common_tls_context; + // Connection idle timeout. Currently used only for SSA. + Duration connection_idle_timeout = Duration::Hours(1); + // Maximum number of outstanding requests can be made to the upstream // cluster. uint32_t max_concurrent_requests = 1024; @@ -101,6 +105,7 @@ struct XdsClusterResource : public XdsResourceType::ResourceData { return type == other.type && lb_policy_config == other.lb_policy_config && lrs_load_reporting_server == other.lrs_load_reporting_server && common_tls_context == other.common_tls_context && + connection_idle_timeout == other.connection_idle_timeout && max_concurrent_requests == other.max_concurrent_requests && outlier_detection == other.outlier_detection && override_host_statuses == other.override_host_statuses; @@ -126,6 +131,7 @@ class XdsClusterResourceType envoy_extensions_clusters_aggregate_v3_ClusterConfig_getmsgdef(symtab); envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_getmsgdef( symtab); + envoy_extensions_upstreams_http_v3_HttpProtocolOptions_getmsgdef(symtab); } }; diff --git a/src/proto/grpc/testing/xds/v3/BUILD b/src/proto/grpc/testing/xds/v3/BUILD index f72941136cc..ff3cfc4f7d7 100644 --- a/src/proto/grpc/testing/xds/v3/BUILD +++ b/src/proto/grpc/testing/xds/v3/BUILD @@ -211,6 +211,16 @@ grpc_proto_library( well_known_protos = True, ) +grpc_proto_library( + name = "http_protocol_options_proto", + srcs = [ + "http_protocol_options.proto", + ], + deps = [ + "protocol_proto", + ], +) + grpc_proto_library( name = "range_proto", srcs = [ diff --git a/src/proto/grpc/testing/xds/v3/cluster.proto b/src/proto/grpc/testing/xds/v3/cluster.proto index 531fbd7e0b8..75c01303d6a 100644 --- a/src/proto/grpc/testing/xds/v3/cluster.proto +++ b/src/proto/grpc/testing/xds/v3/cluster.proto @@ -251,6 +251,8 @@ message Cluster { // maybe by allowing LRS to go on the ADS stream, or maybe by moving some of the negotiation // from the LRS stream here.] core.v3.ConfigSource lrs_server = 42; + + core.v3.TypedExtensionConfig upstream_config = 48; } // Extensible load balancing policy configuration. diff --git a/src/proto/grpc/testing/xds/v3/http_protocol_options.proto b/src/proto/grpc/testing/xds/v3/http_protocol_options.proto new file mode 100644 index 00000000000..8dca945d32d --- /dev/null +++ b/src/proto/grpc/testing/xds/v3/http_protocol_options.proto @@ -0,0 +1,26 @@ +// Copyright 2023 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Local copy of Envoy xDS proto file, used for testing only. + +syntax = "proto3"; + +package envoy.extensions.upstreams.http.v3; + +import "src/proto/grpc/testing/xds/v3/protocol.proto"; + +message HttpProtocolOptions { + // This contains options common across HTTP/1 and HTTP/2 + config.core.v3.HttpProtocolOptions common_http_protocol_options = 1; +} diff --git a/src/proto/grpc/testing/xds/v3/protocol.proto b/src/proto/grpc/testing/xds/v3/protocol.proto index 886cc11ddfb..3a75bdd85b7 100644 --- a/src/proto/grpc/testing/xds/v3/protocol.proto +++ b/src/proto/grpc/testing/xds/v3/protocol.proto @@ -22,6 +22,9 @@ import "google/protobuf/duration.proto"; // [#next-free-field: 5] message HttpProtocolOptions { - // The maximum duration of a connection. + // The connection idle timeout. Defaults to 1h. + google.protobuf.Duration idle_timeout = 1; + + // The maximum duration of a stream. google.protobuf.Duration max_stream_duration = 4; } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c659b30d108..b6f72dccf97 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -215,6 +215,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c', 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c', 'src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c', @@ -373,6 +374,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c', 'src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c', diff --git a/test/core/xds/BUILD b/test/core/xds/BUILD index 4dc271f1cf2..26030f839f5 100644 --- a/test/core/xds/BUILD +++ b/test/core/xds/BUILD @@ -306,6 +306,7 @@ grpc_cc_test( "//src/core:grpc_xds_client", "//src/proto/grpc/testing/xds/v3:aggregate_cluster_proto", "//src/proto/grpc/testing/xds/v3:cluster_proto", + "//src/proto/grpc/testing/xds/v3:http_protocol_options_proto", "//src/proto/grpc/testing/xds/v3:round_robin_proto", "//src/proto/grpc/testing/xds/v3:tls_proto", "//src/proto/grpc/testing/xds/v3:typed_struct_proto", diff --git a/test/core/xds/xds_cluster_resource_type_test.cc b/test/core/xds/xds_cluster_resource_type_test.cc index 27bb75935fb..2feb6199fc2 100644 --- a/test/core/xds/xds_cluster_resource_type_test.cc +++ b/test/core/xds/xds_cluster_resource_type_test.cc @@ -57,6 +57,7 @@ #include "src/proto/grpc/testing/xds/v3/endpoint.pb.h" #include "src/proto/grpc/testing/xds/v3/extension.pb.h" #include "src/proto/grpc/testing/xds/v3/health_check.pb.h" +#include "src/proto/grpc/testing/xds/v3/http_protocol_options.pb.h" #include "src/proto/grpc/testing/xds/v3/outlier_detection.pb.h" #include "src/proto/grpc/testing/xds/v3/round_robin.pb.h" #include "src/proto/grpc/testing/xds/v3/tls.pb.h" @@ -69,6 +70,7 @@ using envoy::extensions::clusters::aggregate::v3::ClusterConfig; using envoy::extensions::load_balancing_policies::round_robin::v3::RoundRobin; using envoy::extensions::load_balancing_policies::wrr_locality::v3::WrrLocality; using envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext; +using envoy::extensions::upstreams::http::v3::HttpProtocolOptions; using xds::type::v3::TypedStruct; namespace grpc_core { @@ -1127,6 +1129,208 @@ TEST_F(LrsTest, NotSelfConfigSource) { << decode_result.resource.status(); } +// +// upstream config tests +// + +using UpstreamConfigTest = XdsClusterTest; + +TEST_F(UpstreamConfigTest, DefaultWithNoUpstreamConfig) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status(); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + auto& resource = + static_cast(**decode_result.resource); + EXPECT_EQ(resource.connection_idle_timeout, Duration::Hours(1)); +} + +TEST_F(UpstreamConfigTest, DefaultWithNoCommonHttpProtocolOptions) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + HttpProtocolOptions http_protocol_options; + cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom( + http_protocol_options); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status(); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + auto& resource = + static_cast(**decode_result.resource); + EXPECT_EQ(resource.connection_idle_timeout, Duration::Hours(1)); +} + +TEST_F(UpstreamConfigTest, DefaultWithFieldUnset) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + HttpProtocolOptions http_protocol_options; + http_protocol_options.mutable_common_http_protocol_options(); + cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom( + http_protocol_options); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status(); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + auto& resource = + static_cast(**decode_result.resource); + EXPECT_EQ(resource.connection_idle_timeout, Duration::Hours(1)); +} + +TEST_F(UpstreamConfigTest, ExplicitlySet) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + HttpProtocolOptions http_protocol_options; + http_protocol_options.mutable_common_http_protocol_options() + ->mutable_idle_timeout() + ->set_seconds(1); + cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom( + http_protocol_options); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status(); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + auto& resource = + static_cast(**decode_result.resource); + EXPECT_EQ(resource.connection_idle_timeout, Duration::Seconds(1)); +} + +TEST_F(UpstreamConfigTest, UnknownUpstreamConfigType) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom( + Cluster()); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + EXPECT_EQ(decode_result.resource.status().code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(decode_result.resource.status().message(), + "errors validating Cluster resource: [" + "field:upstream_config.typed_config.value[" + "envoy.config.cluster.v3.Cluster].type_url " + "error:unsupported upstream config type]") + << decode_result.resource.status(); +} + +TEST_F(UpstreamConfigTest, UnparseableHttpProtocolOptions) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + auto* typed_config = + cluster.mutable_upstream_config()->mutable_typed_config(); + typed_config->PackFrom(HttpProtocolOptions()); + typed_config->set_value(std::string("\0", 1)); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + EXPECT_EQ(decode_result.resource.status().code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(decode_result.resource.status().message(), + "errors validating Cluster resource: [" + "field:upstream_config.typed_config.value[" + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions] " + "error:can't decode HttpProtocolOptions]") + << decode_result.resource.status(); +} + +TEST_F(UpstreamConfigTest, HttpProtocolOptionsInTypedStruct) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + xds::type::v3::TypedStruct typed_struct; + typed_struct.set_type_url( + "types.googleapis.com/" + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions"); + cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom( + typed_struct); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + EXPECT_EQ(decode_result.resource.status().code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(decode_result.resource.status().message(), + "errors validating Cluster resource: [" + "field:upstream_config.typed_config.value[" + "xds.type.v3.TypedStruct].value[" + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions] " + "error:can't decode HttpProtocolOptions]") + << decode_result.resource.status(); +} + +// This is just one example of where ParseDuration() will generate an error, +// to show that we're propagating any such errors correctly. An exhaustive +// set of tests for ParseDuration() is in xds_common_types_test.cc. +TEST_F(UpstreamConfigTest, ErrorsParsingDurations) { + Cluster cluster; + cluster.set_name("foo"); + cluster.set_type(cluster.EDS); + cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self(); + HttpProtocolOptions http_protocol_options; + http_protocol_options.mutable_common_http_protocol_options() + ->mutable_idle_timeout() + ->set_seconds(-1); + cluster.mutable_upstream_config()->mutable_typed_config()->PackFrom( + http_protocol_options); + std::string serialized_resource; + ASSERT_TRUE(cluster.SerializeToString(&serialized_resource)); + auto* resource_type = XdsClusterResourceType::Get(); + auto decode_result = + resource_type->Decode(decode_context_, serialized_resource); + ASSERT_TRUE(decode_result.name.has_value()); + EXPECT_EQ(*decode_result.name, "foo"); + EXPECT_EQ(decode_result.resource.status().code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(decode_result.resource.status().message(), + "errors validating Cluster resource: [" + "field:upstream_config.typed_config.value[" + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions]" + ".common_http_protocol_options.idle_timeout.seconds " + "error:value must be in the range [0, 315576000000]]") + << decode_result.resource.status(); +} + // // circuit breaker tests // diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5e27de762f9..8d399e8d873 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1590,6 +1590,9 @@ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h \ +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h \ +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c \ +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h \ @@ -1987,6 +1990,8 @@ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h \ +src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c \ +src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index c220a387917..095b92ed667 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1365,6 +1365,9 @@ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c \ src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.h \ +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h \ +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c \ +src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb.h \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c \ src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.h \ @@ -1762,6 +1765,8 @@ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h \ +src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c \ +src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h \ src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c \