Revert "Revert "[resource quota] Fix bugs in iomgr and event engine endpoint interactions with resource quota"" (#33499)

Reverts grpc/grpc#33417

Deadlock
https://fusion2.corp.google.com/invocations/99834386-79ff-4707-86eb-52e604774ea9/details
fixed in the c9a1bdc3dc976d73f6e69a319e47f6c86bfc9c1b commit.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 75af5a9..437a132 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1187,6 +1187,7 @@
     add_dependencies(buildtests_cxx resolve_address_using_native_resolver_posix_test)
   endif()
   add_dependencies(buildtests_cxx resolve_address_using_native_resolver_test)
+  add_dependencies(buildtests_cxx resource_quota_end2end_stress_test)
   add_dependencies(buildtests_cxx resource_quota_server_test)
   add_dependencies(buildtests_cxx resource_quota_test)
   add_dependencies(buildtests_cxx retry_cancel_after_first_attempt_starts_test)
@@ -19889,6 +19890,59 @@
 endif()
 if(gRPC_BUILD_TESTS)
 
+add_executable(resource_quota_end2end_stress_test
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.h
+  test/cpp/end2end/resource_quota_end2end_stress_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+target_compile_features(resource_quota_end2end_stress_test PUBLIC cxx_std_14)
+target_include_directories(resource_quota_end2end_stress_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(resource_quota_end2end_stress_test
+  ${_gRPC_BASELIB_LIBRARIES}
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ZLIB_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
 add_executable(resource_quota_server_test
   test/core/end2end/cq_verifier.cc
   test/core/end2end/end2end_test_main.cc
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index dee5255..469e807 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -12074,6 +12074,19 @@
   deps:
   - grpc_test_util
   - grpc++_test_config
+- name: resource_quota_end2end_stress_test
+  gtest: true
+  build: test
+  language: c++
+  headers: []
+  src:
+  - src/proto/grpc/testing/echo.proto
+  - src/proto/grpc/testing/echo_messages.proto
+  - src/proto/grpc/testing/simple_messages.proto
+  - src/proto/grpc/testing/xds/v3/orca_load_report.proto
+  - test/cpp/end2end/resource_quota_end2end_stress_test.cc
+  deps:
+  - grpc++_test_util
 - name: resource_quota_server_test
   gtest: true
   build: test
diff --git a/src/core/BUILD b/src/core/BUILD
index 56bc93e..76978c9 100644
--- a/src/core/BUILD
+++ b/src/core/BUILD
@@ -1841,6 +1841,7 @@
         "time",
         "//:debug_location",
         "//:event_engine_base_hdrs",
+        "//:exec_ctx",
         "//:gpr",
         "//:grpc_public_hdrs",
         "//:ref_counted_ptr",
@@ -1942,6 +1943,7 @@
         "socket_mutator",
         "status_helper",
         "//:event_engine_base_hdrs",
+        "//:exec_ctx",
         "//:gpr",
     ],
 )
diff --git a/src/core/lib/event_engine/posix_engine/posix_endpoint.cc b/src/core/lib/event_engine/posix_engine/posix_endpoint.cc
index b99dde4..6d90c99 100644
--- a/src/core/lib/event_engine/posix_engine/posix_endpoint.cc
+++ b/src/core/lib/event_engine/posix_engine/posix_endpoint.cc
@@ -49,7 +49,9 @@
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/status_helper.h"
 #include "src/core/lib/gprpp/strerror.h"
+#include "src/core/lib/gprpp/sync.h"
 #include "src/core/lib/gprpp/time.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/resource_quota/resource_quota.h"
 #include "src/core/lib/slice/slice.h"
 
@@ -549,28 +551,40 @@
   }
 }
 
-void PosixEndpointImpl::HandleRead(absl::Status status) {
-  read_mu_.Lock();
+bool PosixEndpointImpl::HandleReadLocked(absl::Status& status) {
   if (status.ok() && memory_owner_.is_valid()) {
     MaybeMakeReadSlices();
     if (!TcpDoRead(status)) {
       UpdateRcvLowat();
       // We've consumed the edge, request a new one.
-      read_mu_.Unlock();
-      handle_->NotifyOnRead(on_read_);
-      return;
+      return false;
     }
   } else {
-    if (!memory_owner_.is_valid()) {
-      status = absl::UnknownError("Shutting down endpoint");
+    if (!memory_owner_.is_valid() && status.ok()) {
+      status = TcpAnnotateError(absl::UnknownError("Shutting down endpoint"));
     }
     incoming_buffer_->Clear();
     last_read_buffer_.Clear();
   }
-  absl::AnyInvocable<void(absl::Status)> cb = std::move(read_cb_);
-  read_cb_ = nullptr;
-  incoming_buffer_ = nullptr;
-  read_mu_.Unlock();
+  return true;
+}
+
+void PosixEndpointImpl::HandleRead(absl::Status status) {
+  bool ret = false;
+  absl::AnyInvocable<void(absl::Status)> cb = nullptr;
+  grpc_core::EnsureRunInExecCtx([&, this]() mutable {
+    grpc_core::MutexLock lock(&read_mu_);
+    ret = HandleReadLocked(status);
+    if (ret) {
+      cb = std::move(read_cb_);
+      read_cb_ = nullptr;
+      incoming_buffer_ = nullptr;
+    }
+  });
+  if (!ret) {
+    handle_->NotifyOnRead(on_read_);
+    return;
+  }
   cb(status);
   Unref();
 }
diff --git a/src/core/lib/event_engine/posix_engine/posix_endpoint.h b/src/core/lib/event_engine/posix_engine/posix_endpoint.h
index 8c2fae5..3e8f616 100644
--- a/src/core/lib/event_engine/posix_engine/posix_endpoint.h
+++ b/src/core/lib/event_engine/posix_engine/posix_endpoint.h
@@ -503,7 +503,9 @@
   void UpdateRcvLowat() ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_);
   void HandleWrite(absl::Status status);
   void HandleError(absl::Status status);
-  void HandleRead(absl::Status status);
+  void HandleRead(absl::Status status) ABSL_NO_THREAD_SAFETY_ANALYSIS;
+  bool HandleReadLocked(absl::Status& status)
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_);
   void MaybeMakeReadSlices() ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_);
   bool TcpDoRead(absl::Status& status) ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_);
   void FinishEstimate();
diff --git a/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc b/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
index 98f7a67..59facad 100644
--- a/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
+++ b/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@@ -15,6 +15,7 @@
 #include <grpc/support/port_platform.h>
 
 #include "src/core/lib/event_engine/posix.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/port.h"
 
 #ifdef GRPC_POSIX_SOCKET_TCP
@@ -24,6 +25,7 @@
 #include <unistd.h>      // IWYU pragma: keep
 
 #include <string>
+#include <type_traits>
 #include <utility>
 
 #include "absl/functional/any_invocable.h"
@@ -197,15 +199,20 @@
         listener_->memory_allocator_factory_->CreateMemoryAllocator(
             absl::StrCat("endpoint-tcp-server-connection: ", *peer_name)),
         /*options=*/listener_->options_);
-    // Call on_accept_ and then resume accepting new connections by continuing
-    // the parent for-loop.
-    listener_->on_accept_(
-        /*listener_fd=*/handle_->WrappedFd(), /*endpoint=*/std::move(endpoint),
-        /*is_external=*/false,
-        /*memory_allocator=*/
-        listener_->memory_allocator_factory_->CreateMemoryAllocator(
-            absl::StrCat("on-accept-tcp-server-connection: ", *peer_name)),
-        /*pending_data=*/nullptr);
+
+    grpc_core::EnsureRunInExecCtx([this, peer_name = std::move(*peer_name),
+                                   endpoint = std::move(endpoint)]() mutable {
+      // Call on_accept_ and then resume accepting new connections
+      // by continuing the parent for-loop.
+      listener_->on_accept_(
+          /*listener_fd=*/handle_->WrappedFd(),
+          /*endpoint=*/std::move(endpoint),
+          /*is_external=*/false,
+          /*memory_allocator=*/
+          listener_->memory_allocator_factory_->CreateMemoryAllocator(
+              absl::StrCat("on-accept-tcp-server-connection: ", peer_name)),
+          /*pending_data=*/nullptr);
+    });
   }
   GPR_UNREACHABLE_CODE(return);
 }
@@ -228,21 +235,24 @@
         absl::StrCat("HandleExternalConnection: peer not connected: ",
                      peer_name.status().ToString()));
   }
-  auto endpoint = CreatePosixEndpoint(
-      /*handle=*/poller_->CreateHandle(fd, *peer_name,
-                                       poller_->CanTrackErrors()),
-      /*on_shutdown=*/nullptr, /*engine=*/engine_,
-      /*allocator=*/
-      memory_allocator_factory_->CreateMemoryAllocator(absl::StrCat(
-          "external:endpoint-tcp-server-connection: ", *peer_name)),
-      /*options=*/options_);
-  on_accept_(
-      /*listener_fd=*/listener_fd, /*endpoint=*/std::move(endpoint),
-      /*is_external=*/true,
-      /*memory_allocator=*/
-      memory_allocator_factory_->CreateMemoryAllocator(absl::StrCat(
-          "external:on-accept-tcp-server-connection: ", *peer_name)),
-      /*pending_data=*/pending_data);
+  grpc_core::EnsureRunInExecCtx([this, peer_name = std::move(*peer_name),
+                                 pending_data, listener_fd, fd]() mutable {
+    auto endpoint = CreatePosixEndpoint(
+        /*handle=*/poller_->CreateHandle(fd, peer_name,
+                                         poller_->CanTrackErrors()),
+        /*on_shutdown=*/nullptr, /*engine=*/engine_,
+        /*allocator=*/
+        memory_allocator_factory_->CreateMemoryAllocator(absl::StrCat(
+            "external:endpoint-tcp-server-connection: ", peer_name)),
+        /*options=*/options_);
+    on_accept_(
+        /*listener_fd=*/listener_fd, /*endpoint=*/std::move(endpoint),
+        /*is_external=*/true,
+        /*memory_allocator=*/
+        memory_allocator_factory_->CreateMemoryAllocator(absl::StrCat(
+            "external:on-accept-tcp-server-connection: ", peer_name)),
+        /*pending_data=*/pending_data);
+  });
   return absl::OkStatus();
 }
 
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index 230af79..20d9ebe 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -329,6 +329,17 @@
   static thread_local ApplicationCallbackExecCtx* callback_exec_ctx_;
 };
 
+template <typename F>
+void EnsureRunInExecCtx(F f) {
+  if (ExecCtx::Get() == nullptr) {
+    ApplicationCallbackExecCtx app_ctx;
+    ExecCtx exec_ctx;
+    f();
+  } else {
+    f();
+  }
+}
+
 }  // namespace grpc_core
 
 #endif  // GRPC_SRC_CORE_LIB_IOMGR_EXEC_CTX_H
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index 3b73212..4664d1a 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -729,6 +729,9 @@
   grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
   ZerocopyDisableAndWaitForRemaining(tcp);
   grpc_fd_shutdown(tcp->em_fd, why);
+  tcp->read_mu.Lock();
+  tcp->memory_owner.Reset();
+  tcp->read_mu.Unlock();
 }
 
 static void tcp_free(grpc_tcp* tcp) {
@@ -775,6 +778,9 @@
     gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
     grpc_fd_set_error(tcp->em_fd);
   }
+  tcp->read_mu.Lock();
+  tcp->memory_owner.Reset();
+  tcp->read_mu.Unlock();
   TCP_UNREF(tcp, "destroy");
 }
 
@@ -795,11 +801,14 @@
     ABSL_EXCLUSIVE_LOCKS_REQUIRED(tcp->read_mu) {
   if (!tcp->has_posted_reclaimer) {
     tcp->has_posted_reclaimer = true;
+    TCP_REF(tcp, "posted_reclaimer");
     tcp->memory_owner.PostReclaimer(
         grpc_core::ReclamationPass::kBenign,
         [tcp](absl::optional<grpc_core::ReclamationSweep> sweep) {
-          if (!sweep.has_value()) return;
-          perform_reclamation(tcp);
+          if (sweep.has_value()) {
+            perform_reclamation(tcp);
+          }
+          TCP_UNREF(tcp, "posted_reclaimer");
         });
   }
 }
@@ -1088,7 +1097,7 @@
   }
   tcp->read_mu.Lock();
   grpc_error_handle tcp_read_error;
-  if (GPR_LIKELY(error.ok())) {
+  if (GPR_LIKELY(error.ok()) && tcp->memory_owner.is_valid()) {
     maybe_make_read_slices(tcp);
     if (!tcp_do_read(tcp, &tcp_read_error)) {
       // Maybe update rcv lowat value based on the number of bytes read in this
@@ -1101,7 +1110,12 @@
     }
     tcp_trace_read(tcp, tcp_read_error);
   } else {
-    tcp_read_error = error;
+    if (!tcp->memory_owner.is_valid() && error.ok()) {
+      tcp_read_error =
+          tcp_annotate_error(absl::InternalError("Socket closed"), tcp);
+    } else {
+      tcp_read_error = error;
+    }
     grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
     grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
   }
@@ -2031,6 +2045,9 @@
     gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
     grpc_fd_set_error(tcp->em_fd);
   }
+  tcp->read_mu.Lock();
+  tcp->memory_owner.Reset();
+  tcp->read_mu.Unlock();
   TCP_UNREF(tcp, "destroy");
 }
 
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index f29027c..69b01b6 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -1008,3 +1008,21 @@
         "//test/cpp/util:test_util",
     ],
 )
+
+grpc_cc_test(
+    name = "resource_quota_end2end_stress_test",
+    srcs = ["resource_quota_end2end_stress_test.cc"],
+    external_deps = [
+        "gtest",
+        "absl/strings",
+        "absl/time",
+    ],
+    deps = [
+        "//:grpc++",
+        "//src/core:experiments",
+        "//src/proto/grpc/testing:echo_messages_proto",
+        "//src/proto/grpc/testing:echo_proto",
+        "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_util",
+    ],
+)
diff --git a/test/cpp/end2end/resource_quota_end2end_stress_test.cc b/test/cpp/end2end/resource_quota_end2end_stress_test.cc
new file mode 100644
index 0000000..c475fa1
--- /dev/null
+++ b/test/cpp/end2end/resource_quota_end2end_stress_test.cc
@@ -0,0 +1,154 @@
+// 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 <memory>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/str_cat.h"
+#include "absl/time/time.h"
+
+#include <grpc/support/time.h>
+#include <grpcpp/client_context.h>
+#include <grpcpp/grpcpp.h>
+#include <grpcpp/support/server_callback.h>
+
+#include "src/core/lib/experiments/config.h"
+#include "src/core/lib/gprpp/notification.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+// A stress test which spins up a server with a small configured resource quota
+// value. It then creates many channels which exchange large payloads with the
+// server. This would drive the server to reach resource quota limits and
+// trigger reclamation.
+
+namespace grpc {
+namespace testing {
+namespace {
+constexpr int kResourceQuotaSizeBytes = 1024 * 1024;
+constexpr int kPayloadSizeBytes = 1024 * 1024;
+constexpr int kNumParallelChannels = 1024;
+}  // namespace
+
+class EchoClientUnaryReactor : public grpc::ClientUnaryReactor {
+ public:
+  EchoClientUnaryReactor(ClientContext* ctx, EchoTestService::Stub* stub,
+                         const std::string payload, Status* status)
+      : ctx_(ctx), payload_(payload), status_(status) {
+    ctx_->set_wait_for_ready(true);
+    request_.set_message(payload);
+    stub->async()->Echo(ctx_, &request_, &response_, this);
+    StartCall();
+  }
+
+  void Await() { notification_.WaitForNotification(); }
+
+ protected:
+  void OnReadInitialMetadataDone(bool /*ok*/) override {}
+
+  void OnDone(const Status& s) override {
+    *status_ = s;
+    notification_.Notify();
+  }
+
+ private:
+  ClientContext* const ctx_;
+  EchoRequest request_;
+  EchoResponse response_;
+  const std::string payload_;
+  grpc_core::Notification notification_;
+  Status* const status_;
+};
+
+class EchoServerUnaryReactor : public ServerUnaryReactor {
+ public:
+  EchoServerUnaryReactor(CallbackServerContext* /*ctx*/,
+                         const EchoRequest* request, EchoResponse* response) {
+    response->set_message(request->message());
+    Finish(grpc::Status::OK);
+  }
+
+ private:
+  void OnDone() override { delete this; }
+};
+
+class GrpcCallbackServiceImpl : public EchoTestService::CallbackService {
+ public:
+  ServerUnaryReactor* Echo(CallbackServerContext* context,
+                           const EchoRequest* request,
+                           EchoResponse* response) override {
+    return new EchoServerUnaryReactor(context, request, response);
+  }
+};
+
+class End2EndResourceQuotaUnaryTest : public ::testing::Test {
+ protected:
+  End2EndResourceQuotaUnaryTest() {
+    int port = grpc_pick_unused_port_or_die();
+    server_address_ = absl::StrCat("localhost:", port);
+    payload_ = std::string(kPayloadSizeBytes, 'a');
+    ServerBuilder builder;
+    builder.AddListeningPort(server_address_, InsecureServerCredentials());
+    builder.SetResourceQuota(
+        grpc::ResourceQuota("TestService").Resize(kResourceQuotaSizeBytes));
+    builder.RegisterService(&grpc_service_);
+    server_ = builder.BuildAndStart();
+  }
+
+  ~End2EndResourceQuotaUnaryTest() override { server_->Shutdown(); }
+
+  void MakeGrpcCall() {
+    ClientContext ctx;
+    Status status;
+    auto stub = EchoTestService::NewStub(
+        CreateChannel(server_address_, grpc::InsecureChannelCredentials()));
+    EchoClientUnaryReactor reactor(&ctx, stub.get(), payload_, &status);
+    reactor.Await();
+  }
+
+  void MakeGrpcCalls() {
+    std::vector<std::thread> workers;
+    workers.reserve(kNumParallelChannels);
+    // Run MakeGrpcCall() many times concurrently.
+    for (int i = 0; i < kNumParallelChannels; ++i) {
+      workers.emplace_back([this]() { MakeGrpcCall(); });
+    }
+    for (int i = 0; i < kNumParallelChannels; ++i) {
+      workers[i].join();
+    }
+  }
+
+  int port_;
+  std::unique_ptr<Server> server_;
+  string server_address_;
+  GrpcCallbackServiceImpl grpc_service_;
+  std::string payload_;
+};
+
+TEST_F(End2EndResourceQuotaUnaryTest, MultipleUnaryRPCTest) { MakeGrpcCalls(); }
+
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 08518e8..6c98574 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -7128,6 +7128,30 @@
     "flaky": false,
     "gtest": true,
     "language": "c++",
+    "name": "resource_quota_end2end_stress_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": "resource_quota_server_test",
     "platforms": [
       "linux",