[filter-test] Allow running grpc_init safely (#34567)

Previously it turns out it was not safe to run grpc_init in a filter
test - we'd end up mixing event engine implementations, and causing
undefined behavior at grpc_shutdown.

This change makes it safe and fixes a test internally that's flaking at
70% right now (b/302986486).

---------

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/34191/head^2
Craig Tiller 1 year ago committed by GitHub
parent df1976b590
commit b581a24a4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/core/lib/iomgr/timer_manager.cc
  2. 2
      src/core/lib/iomgr/timer_manager.h
  3. 5
      test/core/filters/client_auth_filter_test.cc
  4. 7
      test/core/filters/client_authority_filter_test.cc
  5. 36
      test/core/filters/filter_test.cc
  6. 5
      test/core/filters/filter_test.h
  7. 5
      test/core/filters/filter_test_test.cc

@ -41,6 +41,8 @@ extern grpc_core::TraceFlag grpc_timer_check_trace;
static gpr_mu g_mu;
// are we multi-threaded
static bool g_threaded;
// should we start multi-threaded
static bool g_start_threaded = true;
// cv to wait until a thread is needed
static gpr_cv g_cv_wait;
// cv for notification when threading ends
@ -309,7 +311,7 @@ void grpc_timer_manager_init(void) {
g_has_timed_waiter = false;
g_timed_waiter_deadline = grpc_core::Timestamp::InfFuture();
start_threads();
if (g_start_threaded) start_threads();
}
static void stop_threads(void) {
@ -351,6 +353,10 @@ void grpc_timer_manager_set_threading(bool enabled) {
}
}
void grpc_timer_manager_set_start_threaded(bool enabled) {
g_start_threaded = enabled;
}
void grpc_kick_poller(void) {
gpr_mu_lock(&g_mu);
g_kicked = true;

@ -32,6 +32,8 @@ void grpc_timer_manager_shutdown(void);
// enable/disable threading - must be called after grpc_timer_manager_init and
// before grpc_timer_manager_shutdown
void grpc_timer_manager_set_threading(bool enabled);
// enable/disable threading - must be called before first grpc init
void grpc_timer_manager_set_start_threaded(bool enabled);
// explicitly perform one tick of the timer system - for when threading is
// disabled
void grpc_timer_manager_tick(void);

@ -139,8 +139,5 @@ TEST_F(ClientAuthFilterTest, RewritesInvalidStatusFromCallCreds) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int retval = RUN_ALL_TESTS();
grpc_shutdown();
return retval;
return RUN_ALL_TESTS();
}

@ -71,10 +71,5 @@ TEST_F(ClientAuthorityFilterTest,
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
// TODO(ctiller): promise_based_call currently demands to instantiate an event
// engine which needs grpc to be initialized.
grpc_init();
int r = RUN_ALL_TESTS();
grpc_shutdown();
return r;
return RUN_ALL_TESTS();
}

@ -15,6 +15,7 @@
#include "test/core/filters/filter_test.h"
#include <algorithm>
#include <chrono>
#include <memory>
#include <queue>
@ -24,8 +25,11 @@
#include "absl/types/optional.h"
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include "src/core/lib/channel/call_finalization.h"
#include "src/core/lib/channel/context.h"
#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/iomgr/timer_manager.h"
#include "src/core/lib/promise/activity.h"
@ -38,6 +42,9 @@
#include "src/core/lib/slice/slice.h"
#include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h"
using grpc_event_engine::experimental::FuzzingEventEngine;
using grpc_event_engine::experimental::GetDefaultEventEngine;
namespace grpc_core {
///////////////////////////////////////////////////////////////////////////////
@ -415,20 +422,27 @@ void FilterTestBase::Call::FinishNextFilter(ServerMetadataHandle md) {
///////////////////////////////////////////////////////////////////////////////
// FilterTestBase
FilterTestBase::FilterTestBase()
: event_engine_(
[]() {
grpc_timer_manager_set_threading(false);
grpc_event_engine::experimental::FuzzingEventEngine::Options
options;
return options;
}(),
fuzzing_event_engine::Actions()) {}
FilterTestBase::FilterTestBase() {
grpc_event_engine::experimental::SetEventEngineFactory([]() {
FuzzingEventEngine::Options options;
options.max_delay_run_after = std::chrono::milliseconds(500);
options.max_delay_write = std::chrono::milliseconds(50);
return std::make_unique<FuzzingEventEngine>(
options, fuzzing_event_engine::Actions());
});
event_engine_ =
std::dynamic_pointer_cast<FuzzingEventEngine>(GetDefaultEventEngine());
grpc_timer_manager_set_start_threaded(false);
grpc_init();
}
FilterTestBase::~FilterTestBase() { event_engine_.UnsetGlobalHooks(); }
FilterTestBase::~FilterTestBase() {
grpc_shutdown();
event_engine_->UnsetGlobalHooks();
}
void FilterTestBase::Step() {
event_engine_.TickUntilIdle();
event_engine_->TickUntilIdle();
::testing::Mock::VerifyAndClearExpectations(&events);
}

@ -206,13 +206,14 @@ class FilterTestBase : public ::testing::Test {
~FilterTestBase() override;
grpc_event_engine::experimental::EventEngine* event_engine() {
return &event_engine_;
return event_engine_.get();
}
void Step();
private:
grpc_event_engine::experimental::FuzzingEventEngine event_engine_;
std::shared_ptr<grpc_event_engine::experimental::FuzzingEventEngine>
event_engine_;
};
template <typename Filter>

@ -246,8 +246,5 @@ TEST_F(NoOpFilterTest, CanProcessServerToClientMessage) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int r = RUN_ALL_TESTS();
grpc_shutdown();
return r;
return RUN_ALL_TESTS();
}

Loading…
Cancel
Save