Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions source/exe/main_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class MainCommon {
public:
MainCommon(int argc, const char* const* argv);
bool run() { return base_.run(); }
// Only tests have a legitimate need for this today.
Event::Dispatcher& dispatcherForTest() { return base_.server()->dispatcher(); }

// Makes an admin-console request by path, calling handler() when complete.
// The caller can initiate this from any thread, but it posts the request
Expand Down
34 changes: 34 additions & 0 deletions test/exe/main_common_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,28 @@ class AdminRequestTest : public MainCommonTest {
}
}

// Wait until Envoy is inside the main server run loop proper. Before entering, Envoy runs any
// pending post callbacks, so it's not reliable to use adminRequest() or post() to do this.
// Generally, tests should not depend on this for correctness, but as a result of
// https://github.com/libevent/libevent/issues/779 we need to for TSAN. This is because the entry
// to event_base_loop() is where the signal base race occurs, but once we're in that loop in
// blocking mode, we're safe to take signals.
// TODO(htuch): Remove when https://github.com/libevent/libevent/issues/779 is fixed.
void waitForEnvoyRun() {
absl::Notification done;
main_common_->dispatcherForTest().post([this, &done] {
struct Sacrifice : Event::DeferredDeletable {
Sacrifice(absl::Notification& notify) : notify_(notify) {}
~Sacrifice() { notify_.Notify(); }
absl::Notification& notify_;
};
auto sacrifice = std::make_unique<Sacrifice>(done);
// Wait for a deferred delete cleanup, this only happens in the main server run loop.
main_common_->dispatcherForTest().deferredDelete(std::move(sacrifice));
});
done.WaitForNotification();
}

// Having triggered Envoy to quit (via signal or /quitquitquit), this blocks until Envoy exits.
bool waitForEnvoyToExit() {
finished_.WaitForNotification();
Expand Down Expand Up @@ -245,6 +267,9 @@ TEST_P(AdminRequestTest, AdminRequestGetStatsAndQuit) {
TEST_P(AdminRequestTest, AdminRequestGetStatsAndKill) {
startEnvoy();
started_.WaitForNotification();
// TODO(htuch): Remove when https://github.com/libevent/libevent/issues/779 is
// fixed, started_ will then become our real synchronization point.
waitForEnvoyRun();
EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("access_log_file.reopen_failed"));
kill(getpid(), SIGTERM);
EXPECT_TRUE(waitForEnvoyToExit());
Expand All @@ -255,6 +280,9 @@ TEST_P(AdminRequestTest, AdminRequestGetStatsAndKill) {
TEST_P(AdminRequestTest, AdminRequestGetStatsAndCtrlC) {
startEnvoy();
started_.WaitForNotification();
// TODO(htuch): Remove when https://github.com/libevent/libevent/issues/779 is
// fixed, started_ will then become our real synchronization point.
waitForEnvoyRun();
EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("access_log_file.reopen_failed"));
kill(getpid(), SIGINT);
EXPECT_TRUE(waitForEnvoyToExit());
Expand All @@ -263,6 +291,9 @@ TEST_P(AdminRequestTest, AdminRequestGetStatsAndCtrlC) {
TEST_P(AdminRequestTest, AdminRequestContentionDisabled) {
startEnvoy();
started_.WaitForNotification();
// TODO(htuch): Remove when https://github.com/libevent/libevent/issues/779 is
// fixed, started_ will then become our real synchronization point.
waitForEnvoyRun();
EXPECT_THAT(adminRequest("/contention", "GET"), HasSubstr("not enabled"));
kill(getpid(), SIGTERM);
EXPECT_TRUE(waitForEnvoyToExit());
Expand All @@ -272,6 +303,9 @@ TEST_P(AdminRequestTest, AdminRequestContentionEnabled) {
addArg("--enable-mutex-tracing");
startEnvoy();
started_.WaitForNotification();
// TODO(htuch): Remove when https://github.com/libevent/libevent/issues/779 is
// fixed, started_ will then become our real synchronization point.
waitForEnvoyRun();

// Induce contention to guarantee a non-zero num_contentions count.
Thread::TestUtil::ContentionGenerator contention_generator;
Expand Down