pull/36732/head
Craig Tiller 11 months ago
parent 88a7d13fd6
commit 78e711c811
  1. 49
      test/core/call/yodel/yodel_test.cc
  2. 27
      test/core/call/yodel/yodel_test.h
  3. 37
      test/core/client_channel/client_channel_test.cc
  4. 10
      test/core/transport/test_suite/transport_test.cc

@ -14,8 +14,11 @@
#include "test/core/call/yodel/yodel_test.h" #include "test/core/call/yodel/yodel_test.h"
#include <memory>
#include "absl/random/random.h" #include "absl/random/random.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/iomgr/timer_manager.h"
#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/resource_quota/resource_quota.h"
@ -103,13 +106,13 @@ void SimpleTestRegistry::RegisterTest(
class YodelTest::WatchDog { class YodelTest::WatchDog {
public: public:
explicit WatchDog(YodelTest* test) : test_(test) {} explicit WatchDog(YodelTest* test) : test_(test) {}
~WatchDog() { test_->event_engine_->Cancel(timer_); } ~WatchDog() { test_->state_->event_engine->Cancel(timer_); }
private: private:
YodelTest* const test_; YodelTest* const test_;
grpc_event_engine::experimental::EventEngine::TaskHandle const timer_{ grpc_event_engine::experimental::EventEngine::TaskHandle const timer_{
test_->event_engine_->RunAfter(Duration::Minutes(5), test_->state_->event_engine->RunAfter(Duration::Minutes(5),
[this]() { test_->Timeout(); })}; [this]() { test_->Timeout(); })};
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -117,36 +120,38 @@ class YodelTest::WatchDog {
YodelTest::YodelTest(const fuzzing_event_engine::Actions& actions, YodelTest::YodelTest(const fuzzing_event_engine::Actions& actions,
absl::BitGenRef rng) absl::BitGenRef rng)
: rng_(rng), : rng_(rng), actions_(actions) {}
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;
}(),
actions)},
call_arena_allocator_{MakeRefCounted<CallArenaAllocator>(
MakeResourceQuota("test-quota")
->memory_quota()
->CreateMemoryAllocator("test-allocator"),
1024)} {}
void YodelTest::RunTest() { void YodelTest::RunTest() {
CoreConfiguration::Reset();
InitCoreConfiguration();
state_ = std::make_unique<State>();
state_->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;
}(),
actions_);
state_->call_arena_allocator = MakeRefCounted<CallArenaAllocator>(
ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator(
"test-allocator"),
1024);
TestImpl(); TestImpl();
EXPECT_EQ(pending_actions_.size(), 0) EXPECT_EQ(pending_actions_.size(), 0)
<< "There are still pending actions: did you forget to call " << "There are still pending actions: did you forget to call "
"WaitForAllPendingWork()?"; "WaitForAllPendingWork()?";
Shutdown(); Shutdown();
event_engine_->TickUntilIdle(); state_->event_engine->TickUntilIdle();
event_engine_->UnsetGlobalHooks(); state_->event_engine->UnsetGlobalHooks();
} }
void YodelTest::TickUntilTrue(absl::FunctionRef<bool()> poll) { void YodelTest::TickUntilTrue(absl::FunctionRef<bool()> poll) {
WatchDog watchdog(this); WatchDog watchdog(this);
while (!poll()) { while (!poll()) {
event_engine_->Tick(); state_->event_engine->Tick();
} }
} }
@ -157,7 +162,7 @@ void YodelTest::WaitForAllPendingWork() {
pending_actions_.pop(); pending_actions_.pop();
continue; continue;
} }
event_engine_->Tick(); state_->event_engine->Tick();
} }
} }

@ -340,7 +340,7 @@ class YodelTest : public ::testing::Test {
yodel_detail::SequenceSpawner( yodel_detail::SequenceSpawner(
name_and_location, name_and_location,
yodel_detail::SpawnerForContext(std::move(context), yodel_detail::SpawnerForContext(std::move(context),
event_engine_.get()), state_->event_engine.get()),
[this](yodel_detail::NameAndLocation name_and_location, int step) { [this](yodel_detail::NameAndLocation name_and_location, int step) {
auto action = std::make_shared<yodel_detail::ActionState>( auto action = std::make_shared<yodel_detail::ActionState>(
name_and_location, step); name_and_location, step);
@ -351,9 +351,10 @@ class YodelTest : public ::testing::Test {
} }
auto MakeCall(ClientMetadataHandle client_initial_metadata) { auto MakeCall(ClientMetadataHandle client_initial_metadata) {
auto* arena = call_arena_allocator_->MakeArena(); auto* arena = state_->call_arena_allocator->MakeArena();
return MakeCallPair(std::move(client_initial_metadata), event_engine_.get(), return MakeCallPair(std::move(client_initial_metadata),
arena, call_arena_allocator_, nullptr); state_->event_engine.get(), arena,
state_->call_arena_allocator, nullptr);
} }
void WaitForAllPendingWork(); void WaitForAllPendingWork();
@ -374,25 +375,33 @@ class YodelTest : public ::testing::Test {
const std::shared_ptr<grpc_event_engine::experimental::FuzzingEventEngine>& const std::shared_ptr<grpc_event_engine::experimental::FuzzingEventEngine>&
event_engine() { event_engine() {
return event_engine_; return state_->event_engine;
} }
private: private:
class WatchDog; class WatchDog;
struct State {
grpc::testing::TestGrpcScope grpc_scope;
std::shared_ptr<grpc_event_engine::experimental::FuzzingEventEngine>
event_engine;
RefCountedPtr<CallArenaAllocator> call_arena_allocator;
};
virtual void TestImpl() = 0; virtual void TestImpl() = 0;
void Timeout(); void Timeout();
void TickUntilTrue(absl::FunctionRef<bool()> poll); void TickUntilTrue(absl::FunctionRef<bool()> poll);
// Called before the test runs, after core configuration has been reset
// and before the event engine is started.
// This is a good time to register any custom core configuration builders.
virtual void InitCoreConfiguration() {}
// Called after the test has run, but before the event engine is shut down. // Called after the test has run, but before the event engine is shut down.
virtual void Shutdown() {} virtual void Shutdown() {}
grpc::testing::TestGrpcScope grpc_scope_;
absl::BitGenRef rng_; absl::BitGenRef rng_;
const std::shared_ptr<grpc_event_engine::experimental::FuzzingEventEngine> fuzzing_event_engine::Actions actions_;
event_engine_; std::unique_ptr<State> state_;
const RefCountedPtr<CallArenaAllocator> call_arena_allocator_;
std::queue<std::shared_ptr<yodel_detail::ActionState>> pending_actions_; std::queue<std::shared_ptr<yodel_detail::ActionState>> pending_actions_;
}; };

@ -18,12 +18,13 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/core/lib/config/core_configuration.h"
#include "test/core/call/yodel/yodel_test.h" #include "test/core/call/yodel/yodel_test.h"
namespace grpc_core { namespace grpc_core {
namespace { namespace {
const absl::string_view kTestTarget = "test_target"; const absl::string_view kTestTarget = "test:///target";
const absl::string_view kTestPath = "/test_method"; const absl::string_view kTestPath = "/test_method";
} // namespace } // namespace
@ -50,6 +51,15 @@ class ClientChannelTest : public YodelTest {
return client_initial_metadata; return client_initial_metadata;
} }
CallHandler TickUntilCallStarted() {
auto poll = [this]() -> Poll<CallHandler> {
auto handler = call_destination_->PopHandler();
if (handler.has_value()) return std::move(*handler);
return Pending();
};
return TickUntil(absl::FunctionRef<Poll<CallHandler>()>(poll));
}
private: private:
class TestClientChannelFactory final : public ClientChannelFactory { class TestClientChannelFactory final : public ClientChannelFactory {
public: public:
@ -62,10 +72,21 @@ class ClientChannelTest : public YodelTest {
class TestCallDestination final : public UnstartedCallDestination { class TestCallDestination final : public UnstartedCallDestination {
public: public:
void StartCall(UnstartedCallHandler unstarted_call_handler) override { void StartCall(UnstartedCallHandler unstarted_call_handler) override {
Crash("unimplemented"); handlers_.push(
unstarted_call_handler.V2HackToStartCallWithoutACallFilterStack());
}
absl::optional<CallHandler> PopHandler() {
if (handlers_.empty()) return absl::nullopt;
auto handler = std::move(handlers_.front());
handlers_.pop();
return handler;
} }
void Orphaned() override {} void Orphaned() override {}
private:
std::queue<CallHandler> handlers_;
}; };
class TestCallDestinationFactory final class TestCallDestinationFactory final
@ -93,6 +114,12 @@ class ClientChannelTest : public YodelTest {
grpc_event_engine::experimental::EventEngine>(event_engine())); grpc_event_engine::experimental::EventEngine>(event_engine()));
} }
void InitCoreConfiguration() override {
CoreConfiguration::RegisterBuilder(
);
}
void Shutdown() override { void Shutdown() override {
channel_.reset(); channel_.reset();
picker_.reset(); picker_.reset();
@ -115,4 +142,10 @@ CLIENT_CHANNEL_TEST(CreateCall) {
channel.CreateCall(MakeClientInitialMetadata()); channel.CreateCall(MakeClientInitialMetadata());
} }
CLIENT_CHANNEL_TEST(StartCall) {
auto& channel = InitChannel(ChannelArgs());
auto call_initiator = channel.CreateCall(MakeClientInitialMetadata());
auto call_handler = TickUntilCallStarted();
}
} // namespace grpc_core } // namespace grpc_core

@ -58,12 +58,10 @@ void TransportTest::ServerCallDestination::StartCall(
} }
absl::optional<CallHandler> TransportTest::ServerCallDestination::PopHandler() { absl::optional<CallHandler> TransportTest::ServerCallDestination::PopHandler() {
if (!handlers_.empty()) { if (handlers_.empty()) return absl::nullopt;
auto handler = std::move(handlers_.front()); auto handler = std::move(handlers_.front());
handlers_.pop(); handlers_.pop();
return handler; return handler;
}
return absl::nullopt;
} }
} // namespace grpc_core } // namespace grpc_core

Loading…
Cancel
Save