|
|
|
@ -14,25 +14,21 @@ |
|
|
|
|
|
|
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
|
|
|
|
|
|
#ifndef GRPC_ENABLE_FORK_SUPPORT |
|
|
|
|
|
|
|
|
|
// Test nothing, everything is fine
|
|
|
|
|
int main(int /* argc */, char** /* argv */) { return 0; } |
|
|
|
|
|
|
|
|
|
#else // GRPC_ENABLE_FORK_SUPPORT
|
|
|
|
|
#include "src/core/lib/event_engine/forkable.h" |
|
|
|
|
|
|
|
|
|
#ifdef GPR_POSIX_SUBPROCESS |
|
|
|
|
#include <errno.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <sys/wait.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#endif // GPR_POSIX_SUBPROCESS
|
|
|
|
|
|
|
|
|
|
#include <gtest/gtest.h> |
|
|
|
|
|
|
|
|
|
#include "absl/time/clock.h" |
|
|
|
|
#include "absl/types/optional.h" |
|
|
|
|
#include "gtest/gtest.h" |
|
|
|
|
|
|
|
|
|
#include <grpc/grpc.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/event_engine/forkable.h" |
|
|
|
|
#include "src/core/lib/gprpp/crash.h" |
|
|
|
|
#include "src/core/lib/config/config_vars.h" |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
using ::grpc_event_engine::experimental::Forkable; |
|
|
|
@ -41,7 +37,7 @@ using ::grpc_event_engine::experimental::RegisterForkHandlers; |
|
|
|
|
|
|
|
|
|
class ForkableTest : public testing::Test {}; |
|
|
|
|
|
|
|
|
|
#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK |
|
|
|
|
#ifdef GPR_POSIX_SUBPROCESS |
|
|
|
|
TEST_F(ForkableTest, BasicPthreadAtForkOperations) { |
|
|
|
|
class SomeForkable : public Forkable { |
|
|
|
|
public: |
|
|
|
@ -50,15 +46,27 @@ TEST_F(ForkableTest, BasicPthreadAtForkOperations) { |
|
|
|
|
void PostforkChild() override { child_called_ = true; } |
|
|
|
|
|
|
|
|
|
void CheckParent() { |
|
|
|
|
#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK |
|
|
|
|
EXPECT_TRUE(prepare_called_); |
|
|
|
|
EXPECT_TRUE(parent_called_); |
|
|
|
|
EXPECT_FALSE(child_called_); |
|
|
|
|
#else |
|
|
|
|
EXPECT_FALSE(prepare_called_); |
|
|
|
|
EXPECT_FALSE(parent_called_); |
|
|
|
|
EXPECT_FALSE(child_called_); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CheckChild() { |
|
|
|
|
#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK |
|
|
|
|
EXPECT_TRUE(prepare_called_); |
|
|
|
|
EXPECT_FALSE(parent_called_); |
|
|
|
|
EXPECT_TRUE(child_called_); |
|
|
|
|
#else |
|
|
|
|
EXPECT_FALSE(prepare_called_); |
|
|
|
|
EXPECT_FALSE(parent_called_); |
|
|
|
|
EXPECT_FALSE(child_called_); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
@ -92,13 +100,50 @@ TEST_F(ForkableTest, BasicPthreadAtForkOperations) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
|
|
|
|
|
#endif // GPR_POSIX_SUBPROCESS
|
|
|
|
|
|
|
|
|
|
TEST_F(ForkableTest, NonPthreadManualForkOperations) { |
|
|
|
|
// Manually simulates a fork event for non-pthread-enabled environments
|
|
|
|
|
#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK |
|
|
|
|
// This platform does not need to exercise fork support manually.
|
|
|
|
|
GTEST_SKIP("Unnecessary test, this platform supports pthreads."); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
class SomeForkable : public Forkable { |
|
|
|
|
public: |
|
|
|
|
void PrepareFork() override { prepare_called_ = true; } |
|
|
|
|
void PostforkParent() override { parent_called_ = true; } |
|
|
|
|
void PostforkChild() override { child_called_ = true; } |
|
|
|
|
|
|
|
|
|
void AssertStates(bool prepare, bool parent, bool child) { |
|
|
|
|
EXPECT_EQ(prepare_called_, prepare); |
|
|
|
|
EXPECT_EQ(parent_called_, parent); |
|
|
|
|
EXPECT_EQ(child_called_, child); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
bool prepare_called_ = false; |
|
|
|
|
bool parent_called_ = false; |
|
|
|
|
bool child_called_ = false; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
SomeForkable forkable; |
|
|
|
|
forkable.AssertStates(/*prepare=*/false, /*parent=*/false, /*child=*/false); |
|
|
|
|
grpc_event_engine::experimental::PrepareFork(); |
|
|
|
|
forkable.AssertStates(/*prepare=*/true, /*parent=*/false, /*child=*/false); |
|
|
|
|
grpc_event_engine::experimental::PostforkParent(); |
|
|
|
|
forkable.AssertStates(/*prepare=*/true, /*parent=*/true, /*child=*/false); |
|
|
|
|
grpc_event_engine::experimental::PostforkChild(); |
|
|
|
|
forkable.AssertStates(/*prepare=*/true, /*parent=*/true, /*child=*/true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) { |
|
|
|
|
testing::InitGoogleTest(&argc, argv); |
|
|
|
|
// Force enable fork support to allow testing the fork handler registry.
|
|
|
|
|
grpc_core::ConfigVars::Overrides config_overrides; |
|
|
|
|
config_overrides.enable_fork_support = true; |
|
|
|
|
grpc_core::ConfigVars::SetOverrides(config_overrides); |
|
|
|
|
RegisterForkHandlers(); |
|
|
|
|
auto result = RUN_ALL_TESTS(); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif // GRPC_ENABLE_FORK_SUPPORT
|
|
|
|
|