// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Epoll tests which determine that the right things happen in the right order.
// Also lots of testing of individual functions.

#include "quiche/epoll_server/simple_epoll_server.h"

#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <unistd.h>

#include <algorithm>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "absl/time/clock.h"
#include "quiche/epoll_server/fake_simple_epoll_server.h"
#include "quiche/epoll_server/platform/api/epoll_address_test_utils.h"
#include "quiche/epoll_server/platform/api/epoll_expect_bug.h"
#include "quiche/epoll_server/platform/api/epoll_test.h"
#include "quiche/epoll_server/platform/api/epoll_thread.h"

namespace epoll_server {

namespace test {

namespace {

const int kPageSize = 4096;
const int kMaxBufLen = 10000;

// These are used to record what is happening.
enum {
  CREATION,
  REGISTRATION,
  MODIFICATION,
  EVENT,
  UNREGISTRATION,
  SHUTDOWN,
  DESTRUCTION
};

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

int64_t WallTimeNowInUsec() { return absl::GetCurrentTimeNanos() / 1000; }

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

struct RecordEntry {
  RecordEntry() : time(0), instance(nullptr), event_type(0), fd(0), data(0) {}

  RecordEntry(int64_t time, void* instance, int event_type, int fd, int data)
      : time(time),
        instance(instance),
        event_type(event_type),
        fd(fd),
        data(data) {}

  int64_t time;
  void* instance;
  int event_type;
  int fd;
  int data;

  bool IsEqual(const RecordEntry* entry) const {
    bool retval = true;

    if (instance != entry->instance) {
      retval = false;
      EPOLL_LOG(INFO) << " instance (" << instance << ") != entry->instance("
                      << entry->instance << ")";
    }
    if (event_type != entry->event_type) {
      retval = false;
      EPOLL_LOG(INFO) << " event_type (" << event_type
                      << ") != entry->event_type(" << entry->event_type << ")";
    }
    if (fd != entry->fd) {
      retval = false;
      EPOLL_LOG(INFO) << " fd (" << fd << ") != entry->fd (" << entry->fd
                      << ")";
    }
    if (data != entry->data) {
      retval = false;
      EPOLL_LOG(INFO) << " data (" << data << ") != entry->data(" << entry->data
                      << ")";
    }
    return retval;
  }
};

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

class Recorder {
 public:
  void Record(void* instance, int event_type, int fd, int data) {
    records_.push_back(
        RecordEntry(WallTimeNowInUsec(), instance, event_type, fd, data));
  }

  const std::vector<RecordEntry>* records() const { return &records_; }

  bool IsEqual(const Recorder* recorder) const {
    const std::vector<RecordEntry>* records = recorder->records();

    if (records_.size() != records->size()) {
      EPOLL_LOG(INFO) << "records_.size() (" << records_.size()
                      << ") != records->size() (" << records->size() << ")";
      return false;
    }
    for (size_t i = 0; i < std::min(records_.size(), records->size()); ++i) {
      if (!records_[i].IsEqual(&(*records)[i])) {
        EPOLL_LOG(INFO) << "entry in index: " << i << " differs from recorder.";
        return false;
      }
    }
    return true;
  }

 private:
  std::vector<RecordEntry> records_;
};

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

class RecordingCB : public EpollCallbackInterface {
 public:
  RecordingCB() : recorder_(new Recorder()) {
    recorder_->Record(this, CREATION, 0, 0);
  }

  ~RecordingCB() override {
    recorder_->Record(this, DESTRUCTION, 0, 0);
    delete recorder_;
  }

  void OnRegistration(SimpleEpollServer* /*eps*/, int fd,
                      int event_mask) override {
    recorder_->Record(this, REGISTRATION, fd, event_mask);
  }

  void OnModification(int fd, int event_mask) override {
    recorder_->Record(this, MODIFICATION, fd, event_mask);
  }

  void OnEvent(int fd, EpollEvent* event) override {
    recorder_->Record(this, EVENT, fd, event->in_events);
    if (event->in_events & EPOLLIN) {
      const int kLength = 1024;
      char buf[kLength];
      int data_read;
      do {
        data_read = read(fd, &buf, kLength);
      } while (data_read > 0);
    }
  }

  void OnUnregistration(int fd, bool replaced) override {
    recorder_->Record(this, UNREGISTRATION, fd, replaced);
  }

  void OnShutdown(SimpleEpollServer* eps, int fd) override {
    if (fd >= 0) {
      eps->UnregisterFD(fd);
    }
    recorder_->Record(this, SHUTDOWN, fd, 0);
  }

  std::string Name() const override { return "RecordingCB"; }

  const Recorder* recorder() const { return recorder_; }

 protected:
  Recorder* recorder_;
};

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// A simple test server that adds some test functions to SimpleEpollServer as
// well as allowing access to protected functions.
class EpollTestServer : public SimpleEpollServer {
 public:
  EpollTestServer() : SimpleEpollServer() {}

  ~EpollTestServer() override {}

  void CheckMapping(int fd, CB* cb) {
    CBAndEventMask tmp;
    tmp.fd = fd;
    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
    CHECK(fd_i != cb_map_.end());  // Chokes CHECK_NE.
    CHECK(fd_i->cb == cb);
  }

  void CheckNotMapped(int fd) {
    CBAndEventMask tmp;
    tmp.fd = fd;
    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
    CHECK(fd_i == cb_map_.end());  // Chokes CHECK_EQ.
  }

  void CheckEventMask(int fd, int event_mask) {
    CBAndEventMask tmp;
    tmp.fd = fd;
    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
    CHECK(cb_map_.end() != fd_i);  // Chokes CHECK_NE.
    CHECK_EQ(fd_i->event_mask, event_mask);
  }

  void CheckNotRegistered(int fd) {
    struct epoll_event ee;
    memset(&ee, 0, sizeof(ee));
    // If the fd is registered, the epoll_ctl call would succeed (return 0) and
    // the CHECK would fail.
    CHECK(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee));
  }

  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }

  bool ContainsAlarm(AlarmCB* ac) {
    return all_alarms_.find(ac) != all_alarms_.end();
  }

  using SimpleEpollServer::WaitForEventsAndCallHandleEvents;
};

class EpollFunctionTest : public EpollTest {
 public:
  EpollFunctionTest()
      : fd_(-1), fd2_(-1), recorder_(nullptr), cb_(nullptr), ep_(nullptr) {}

  ~EpollFunctionTest() override {
    delete ep_;
    delete cb_;
  }

  void SetUp() override {
    ep_ = new EpollTestServer();
    cb_ = new RecordingCB();
    // recorder_ is safe to use directly as we know it has the same scope as
    // cb_
    recorder_ = cb_->recorder();

    int pipe_fds[2];
    if (pipe(pipe_fds) < 0) {
      EPOLL_PLOG(FATAL) << "pipe() failed";
    }
    fd_ = pipe_fds[0];
    fd2_ = pipe_fds[1];
  }

  void TearDown() override {
    close(fd_);
    close(fd2_);
  }

  void DeleteSimpleEpollServer() {
    delete ep_;
    ep_ = nullptr;
  }

  int fd() { return fd_; }
  int fd2() { return fd2_; }
  EpollTestServer* ep() { return ep_; }
  EpollCallbackInterface* cb() { return cb_; }
  const Recorder* recorder() { return recorder_; }

 private:
  int fd_;
  int fd2_;
  const Recorder* recorder_;
  RecordingCB* cb_;
  EpollTestServer* ep_;
};

TEST_F(EpollFunctionTest, TestUnconnectedSocket) {
  int fd = socket(AddressFamilyUnderTest(), SOCK_STREAM, IPPROTO_TCP);
  ep()->RegisterFD(fd, cb(), EPOLLIN | EPOLLOUT);
  ep()->WaitForEventsAndExecuteCallbacks();

  Recorder tmp;
  tmp.Record(cb(), CREATION, 0, 0);
  tmp.Record(cb(), REGISTRATION, fd, EPOLLIN | EPOLLOUT);
  tmp.Record(cb(), EVENT, fd, EPOLLOUT | EPOLLHUP);
  EXPECT_TRUE(recorder()->IsEqual(&tmp));
}

TEST_F(EpollFunctionTest, TestRegisterFD) {
  // Check that the basic register works.
  ep()->RegisterFD(fd(), cb(), EPOLLIN);

  // Make sure that the fd-CB mapping is there.
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN);

  // Now make sure that if we register again, we stomp the old callback.
  // Also make sure we handle O_NONBLOCK correctly
  RecordingCB cb2;
  ep()->RegisterFD(fd(), &cb2, EPOLLOUT | O_NONBLOCK);
  ep()->CheckMapping(fd(), &cb2);
  ep()->CheckEventMask(fd(), EPOLLOUT | O_NONBLOCK);

  // Clean up.
  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestRegisterFDForWrite) {
  ep()->RegisterFDForWrite(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLOUT);

  // Clean up.
  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestRegisterFDForReadWrite) {
  ep()->RegisterFDForReadWrite(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);

  // Clean up.
  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestRegisterFDForRead) {
  ep()->RegisterFDForRead(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN);

  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestUnregisterFD) {
  ep()->RegisterFDForRead(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN);

  // Unregister and make sure that it's gone.
  ep()->UnregisterFD(fd());
  ep()->CheckNotMapped(fd());
  ep()->CheckNotRegistered(fd());

  // And make sure that unregistering something a second time doesn't cause
  // crashes.
  ep()->UnregisterFD(fd());
  ep()->CheckNotMapped(fd());
  ep()->CheckNotRegistered(fd());
}

TEST_F(EpollFunctionTest, TestModifyCallback) {
  // Check that nothing terrible happens if we modify an unregistered fd.
  ep()->ModifyCallback(fd(), EPOLLOUT);
  ep()->CheckNotMapped(fd());
  ep()->CheckNotRegistered(fd());

  // Check that the basic register works.
  ep()->RegisterFD(fd(), cb(), EPOLLIN);
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN);

  // Check that adding a signal swaps it out for the first.
  ep()->ModifyCallback(fd(), EPOLLOUT);
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLOUT);

  // Check that modifying from X to X works correctly.
  ep()->ModifyCallback(fd(), EPOLLOUT);
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLOUT);

  // Check that modifying from something to nothing works.
  ep()->ModifyCallback(fd(), 0);
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), 0);

  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestStopRead) {
  ep()->RegisterFDForReadWrite(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);

  // Unregister and make sure you only lose the read event.
  ep()->StopRead(fd());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLOUT);

  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestStartRead) {
  ep()->RegisterFDForWrite(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLOUT);

  // Make sure that StartRead adds EPOLLIN and doesn't remove other signals.
  ep()->StartRead(fd());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);

  // Clean up.
  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestStopWrite) {
  ep()->RegisterFDForReadWrite(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);

  // Unregister write and make sure you only lose the write event.
  ep()->StopWrite(fd());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN);

  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestStartWrite) {
  ep()->RegisterFDForRead(fd(), cb());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN);

  // Make sure that StartWrite adds EPOLLOUT and doesn't remove other
  // signals.
  ep()->StartWrite(fd());
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);

  // Clean up.
  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestSet_timeout_in_us) {
  // Check that set works with various values.  There's a separate test below
  // to make sure the values are used properly.
  ep()->set_timeout_in_us(10);
  EXPECT_EQ(10, ep()->timeout_in_us_for_test());

  ep()->set_timeout_in_us(-1);
  EXPECT_EQ(-1, ep()->timeout_in_us_for_test());
}

TEST_F(EpollFunctionTest, TestHandleEvent) {
  const std::vector<RecordEntry>* records = recorder()->records();

  // Test that nothing bad happens if the FD is not in the map.
  ep()->HandleEvent(fd(), EPOLLOUT);
  ep()->CallReadyListCallbacks();

  ep()->RegisterFD(fd(), cb(), 0);
  ep()->CheckMapping(fd(), cb());
  ep()->CheckEventMask(fd(), 0);

  // At this point we should have creation and registration recorded.
  EXPECT_EQ(2u, records->size());

  // Call handle event and make sure something was recorded.
  ep()->HandleEvent(fd(), EPOLLOUT);
  ep()->CallReadyListCallbacks();
  EXPECT_EQ(3u, records->size());

  // Call handle event and make sure something was recorded.
  ep()->HandleEvent(fd(), EPOLLIN | O_NONBLOCK);
  ep()->CallReadyListCallbacks();
  EXPECT_EQ(4u, records->size());

  Recorder tmp;
  tmp.Record(cb(), CREATION, 0, 0);
  tmp.Record(cb(), REGISTRATION, fd(), 0);
  tmp.Record(cb(), EVENT, fd(), EPOLLOUT);
  tmp.Record(cb(), EVENT, fd(), EPOLLIN | O_NONBLOCK);

  EXPECT_TRUE(recorder()->IsEqual(&tmp));
  ep()->UnregisterFD(fd());
}

TEST_F(EpollFunctionTest, TestNumFDsRegistered) {
  EXPECT_EQ(0, ep()->NumFDsRegistered());

  ep()->RegisterFD(fd(), cb(), 0);
  EXPECT_EQ(1, ep()->NumFDsRegistered());

  ep()->RegisterFD(fd2(), cb(), 0);
  EXPECT_EQ(2, ep()->NumFDsRegistered());

  ep()->RegisterFD(fd2(), cb(), 0);
  EXPECT_EQ(2, ep()->NumFDsRegistered());

  ep()->UnregisterFD(fd2());
  EXPECT_EQ(1, ep()->NumFDsRegistered());

  ep()->UnregisterFD(fd());
  EXPECT_EQ(0, ep()->NumFDsRegistered());
}

// Check all of the individual signals and 1-2 combinations.
TEST_F(EpollFunctionTest, TestEventMaskToString) {
  std::string test;

  test = SimpleEpollServer::EventMaskToString(EPOLLIN);
  EXPECT_EQ(test, "EPOLLIN ");

  test = SimpleEpollServer::EventMaskToString(EPOLLOUT);
  EXPECT_EQ(test, "EPOLLOUT ");

  test = SimpleEpollServer::EventMaskToString(EPOLLPRI);
  EXPECT_EQ(test, "EPOLLPRI ");

  test = SimpleEpollServer::EventMaskToString(EPOLLERR);
  EXPECT_EQ(test, "EPOLLERR ");

  test = SimpleEpollServer::EventMaskToString(EPOLLHUP);
  EXPECT_EQ(test, "EPOLLHUP ");

  test = SimpleEpollServer::EventMaskToString(EPOLLHUP | EPOLLIN);
  EXPECT_EQ(test, "EPOLLIN EPOLLHUP ");

  test = SimpleEpollServer::EventMaskToString(EPOLLIN | EPOLLOUT);
  EXPECT_EQ(test, "EPOLLIN EPOLLOUT ");
}

class TestAlarm : public EpollAlarmCallbackInterface {
 public:
  TestAlarm()
      : time_before_next_alarm_(-1),
        was_called_(false),
        num_called_(0),
        absolute_time_(false),
        onshutdown_called_(false),
        has_token_(false),
        eps_(nullptr) {}
  ~TestAlarm() override {}
  int64_t OnAlarm() override {
    has_token_ = false;
    was_called_ = true;
    ++num_called_;
    if (time_before_next_alarm_ < 0) {
      return 0;
    }
    if (absolute_time_) {
      return time_before_next_alarm_;
    } else {
      return WallTimeNowInUsec() + time_before_next_alarm_;
    }
  }

  void OnShutdown(SimpleEpollServer* /*eps*/) override {
    onshutdown_called_ = true;
    has_token_ = false;
  }
  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
                      SimpleEpollServer* eps) override {
    has_token_ = true;
    last_token_ = token;
    eps_ = eps;
  }
  void OnUnregistration() override { has_token_ = false; }

  void UnregisterIfRegistered(SimpleEpollServer* eps) {
    if (has_token_) {
      eps->UnregisterAlarm(last_token_);
    }
  }

  void ReregisterAlarm(int64_t timeout_in_us) {
    CHECK(has_token_);
    eps_->ReregisterAlarm(last_token_, timeout_in_us);
  }

  void Reset() {
    time_before_next_alarm_ = -1;
    was_called_ = false;
    absolute_time_ = false;
  }

  bool was_called() const { return was_called_; }
  int num_called() const { return num_called_; }

  void set_time_before_next_alarm(int64_t time) {
    time_before_next_alarm_ = time;
  }
  void set_absolute_time(bool absolute) { absolute_time_ = absolute; }
  bool onshutdown_called() { return onshutdown_called_; }

 protected:
  int64_t time_before_next_alarm_;
  bool was_called_;
  int num_called_;
  // Is time_before_next_alarm relative to the current time or absolute?
  bool absolute_time_;
  bool onshutdown_called_;
  bool has_token_;
  SimpleEpollServer::AlarmRegToken last_token_;
  SimpleEpollServer* eps_;
};

class TestChildAlarm;

// This node unregister all other alarms when it receives
// OnShutdown() from any one child.
class TestParentAlarm {
 public:
  void OnShutdown(TestChildAlarm* child, SimpleEpollServer* eps) {
    // Unregister
    for (ChildTokenMap::const_iterator it = child_tokens_.begin();
         it != child_tokens_.end(); ++it) {
      if (it->first != child) {
        eps->UnregisterAlarm(it->second);
      }
    }
    child_tokens_.clear();
  }

  void OnRegistration(TestChildAlarm* child,
                      const SimpleEpollServer::AlarmRegToken& token) {
    child_tokens_[child] = token;
  }

 protected:
  typedef std::unordered_map<TestChildAlarm*, SimpleEpollServer::AlarmRegToken>
      ChildTokenMap;

  ChildTokenMap child_tokens_;
};

class TestChildAlarm : public TestAlarm {
 public:
  void set_parent(TestParentAlarm* tp) { parent_ = tp; }
  void OnShutdown(SimpleEpollServer* eps) override {
    onshutdown_called_ = true;
    // Inform parent of shutdown
    parent_->OnShutdown(this, eps);
  }
  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
                      SimpleEpollServer* /*eps*/) override {
    parent_->OnRegistration(this, token);
  }

 protected:
  TestParentAlarm* parent_;
};

class TestAlarmThatRegistersAnotherAlarm : public TestAlarm {
 public:
  TestAlarmThatRegistersAnotherAlarm()
      : alarm_(nullptr),
        reg_time_delta_usec_(0),
        eps_to_register_(nullptr),
        has_reg_alarm_(false) {}
  void SetRegisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
                        SimpleEpollServer* eps) {
    alarm_ = alarm;
    reg_time_delta_usec_ = time_delta_usec;
    has_reg_alarm_ = true;
    eps_to_register_ = eps;
  }
  int64_t OnAlarm() override {
    if (has_reg_alarm_) {
      eps_to_register_->RegisterAlarm(
          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
          alarm_);
      has_reg_alarm_ = false;
    }
    return TestAlarm::OnAlarm();
  }

 protected:
  TestAlarm* alarm_;
  int64_t reg_time_delta_usec_;
  SimpleEpollServer* eps_to_register_;
  bool has_reg_alarm_;
};

class TestAlarmThatRegistersAndReregistersAnotherAlarm : public TestAlarm {
 public:
  TestAlarmThatRegistersAndReregistersAnotherAlarm()
      : alarm_(nullptr),
        reg_time_delta_usec_(0),
        reregister_time_delta_usec_(0),
        eps_to_register_(nullptr),
        has_reg_alarm_(false) {}
  void SetRegisterAndReregisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
                                     int64_t reregister_delta_usec,
                                     SimpleEpollServer* eps) {
    alarm_ = alarm;
    reg_time_delta_usec_ = time_delta_usec;
    reregister_time_delta_usec_ = reregister_delta_usec;
    has_reg_alarm_ = true;
    eps_to_register_ = eps;
  }
  int64_t OnAlarm() override {
    if (has_reg_alarm_) {
      eps_to_register_->RegisterAlarm(
          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
          alarm_);
      alarm_->ReregisterAlarm(eps_to_register_->ApproximateNowInUsec() +
                              reregister_time_delta_usec_);
      has_reg_alarm_ = false;
    }
    return TestAlarm::OnAlarm();
  }

 protected:
  TestAlarm* alarm_;
  int64_t reg_time_delta_usec_;
  int64_t reregister_time_delta_usec_;
  SimpleEpollServer* eps_to_register_;
  bool has_reg_alarm_;
};

class TestAlarmThatUnregistersAnotherAlarm : public TestAlarm {
 public:
  TestAlarmThatUnregistersAnotherAlarm()
      : alarm_(nullptr), eps_to_register_(nullptr), has_unreg_alarm_(false) {}
  void SetUnregisterAlarm(TestAlarm* alarm, SimpleEpollServer* eps) {
    alarm_ = alarm;
    has_unreg_alarm_ = true;
    eps_to_register_ = eps;
  }
  int64_t OnAlarm() override {
    if (has_unreg_alarm_) {
      has_unreg_alarm_ = false;
      alarm_->UnregisterIfRegistered(eps_to_register_);
    }
    return TestAlarm::OnAlarm();
  }

 protected:
  TestAlarm* alarm_;
  SimpleEpollServer* eps_to_register_;
  bool has_unreg_alarm_;
};

class TestAlarmUnregister : public TestAlarm {
 public:
  TestAlarmUnregister()
      : onunregistration_called_(false), iterator_token_(nullptr) {}
  ~TestAlarmUnregister() override { delete iterator_token_; }

  void OnShutdown(SimpleEpollServer* /*eps*/) override {
    onshutdown_called_ = true;
  }

  int64_t OnAlarm() override {
    delete iterator_token_;
    iterator_token_ = nullptr;

    return TestAlarm::OnAlarm();
  }

  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
                      SimpleEpollServer* /*eps*/) override {
    // Multiple iterator tokens are not maintained by this code,
    // so we should have reset the iterator_token in OnAlarm or
    // OnUnregistration.
    CHECK(iterator_token_ == nullptr);
    iterator_token_ = new SimpleEpollServer::AlarmRegToken(token);
  }
  void OnUnregistration() override {
    delete iterator_token_;
    iterator_token_ = nullptr;
    // Make sure that this alarm was not already unregistered.
    CHECK(onunregistration_called_ == false);
    onunregistration_called_ = true;
  }

  bool onunregistration_called() { return onunregistration_called_; }
  // Returns true if the token has been filled in with the saved iterator
  // and false if it has not.
  bool get_token(SimpleEpollServer::AlarmRegToken* token) {
    if (iterator_token_ != nullptr) {
      *token = *iterator_token_;
      return true;
    } else {
      return false;
    }
  }

 protected:
  bool onunregistration_called_;
  SimpleEpollServer::AlarmRegToken* iterator_token_;
};

void WaitForAlarm(SimpleEpollServer* eps, const TestAlarm& alarm) {
  for (int i = 0; i < 5; ++i) {
    // Ideally we would only have to call this once but it could wake up a bit
    // early and so not call the alarm.  If it wakes up early several times
    // there is something wrong.
    eps->WaitForEventsAndExecuteCallbacks();
    if (alarm.was_called()) {
      break;
    }
  }
}

// Check a couple of alarm times to make sure they're falling within a
// reasonable range.
TEST(SimpleEpollServerTest, TestAlarms) {
  EpollTestServer ep;
  TestAlarm alarm;

  int alarm_time = 10;

  // Register an alarm and make sure we wait long enough to hit it.
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  WaitForAlarm(&ep, alarm);
  EXPECT_TRUE(alarm.was_called());
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  alarm.Reset();

  // Test a different time just to be careful.
  alarm_time = 20;
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  WaitForAlarm(&ep, alarm);
  EXPECT_TRUE(alarm.was_called());
  alarm.Reset();

  // The alarm was a one-time thing.  Make sure that we don't hit it again.
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_FALSE(alarm.was_called());
  alarm.Reset();
}

// Same as above, but using RegisterAlarmApproximateDelta.
TEST(SimpleEpollServerTest, TestRegisterAlarmApproximateDelta) {
  EpollTestServer ep;
  TestAlarm alarm;

  int alarm_time = 10;

  // Register an alarm and make sure we wait long enough to hit it.
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  WaitForAlarm(&ep, alarm);
  EXPECT_TRUE(alarm.was_called());
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  alarm.Reset();
  int64_t first_now = ep.ApproximateNowInUsec();
  EXPECT_LT(0u, first_now);

  // Test a different time just to be careful.
  alarm_time = 20;
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  WaitForAlarm(&ep, alarm);
  EXPECT_TRUE(alarm.was_called());
  alarm.Reset();
  int64_t second_now = ep.ApproximateNowInUsec();

  EXPECT_LT(first_now, second_now);

  // The alarm was a one-time thing.  Make sure that we don't hit it again.
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_FALSE(alarm.was_called());
  alarm.Reset();
}

TEST(SimpleEpollServerTest, TestAlarmsWithInfiniteWait) {
  EpollTestServer ep;
  TestAlarm alarm;

  int alarm_time = 10;

  // Register an alarm and make sure we wait long enough to hit it.
  ep.set_timeout_in_us(-1);
  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  WaitForAlarm(&ep, alarm);
  EXPECT_TRUE(alarm.was_called());
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  alarm.Reset();
}

// In this test we have an alarm that when fires gets re-registered
// at almost the same time at which it fires. Here, we want to make
// sure that when the alarm gets re-registered we do not call OnAlarm()
// on the same Alarm object again, until we have called
// WaitForEventsAndExecuteCallbacks(). A poor implementation of epoll
// server alarm handling can potentially cause OnAlarm() to be called
// multiple times. We make sure that the epoll server is not going in
// an infinite loop by checking that OnAlarm() is called exactly once
// on the alarm object that got registered again.
TEST(SimpleEpollServerTest, TestAlarmsThatGetReRegisteredAreNotCalledTwice) {
  // This alarm would get registered again
  TestAlarm alarm;
  TestAlarm alarm2;
  EpollTestServer ep;
  ep.set_timeout_in_us(-1);

  int64_t alarm_time = 10;
  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;

  // This will make the alarm re-register when OnAlarm is called.
  alarm.set_absolute_time(true);
  alarm.set_time_before_next_alarm(abs_time + 2);

  // Register two alarms and make sure we wait long enough to hit it.
  ep.RegisterAlarm(abs_time, &alarm);
  ep.RegisterAlarm(abs_time, &alarm2);
  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());

  WaitForAlarm(&ep, alarm);

  EXPECT_TRUE(alarm.was_called());
  // Make sure that alarm is called only once.
  EXPECT_EQ(1, alarm.num_called());
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  alarm.Reset();
}

// Here we make sure that when one alarm unregisters another alarm
// (that is supposed to be registered again because its OnAlarm
// returned > 0), the alarm thats supposed to be unregistered does
// actually gets unregistered.
TEST(SimpleEpollServerTest, TestAlarmsOneOnAlarmUnRegistersAnotherAlarm) {
  TestAlarm alarm;
  TestAlarmThatUnregistersAnotherAlarm alarm2;
  EpollTestServer ep;
  ep.set_timeout_in_us(-1);

  int64_t alarm_time = 1;
  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;

  // This will make the alarm re-register when OnAlarm is called.
  alarm.set_absolute_time(true);
  alarm.set_time_before_next_alarm(abs_time + 2);

  // Register two alarms and make sure we wait long enough to hit it.
  ep.RegisterAlarm(abs_time, &alarm);
  // This would cause us to unregister alarm when OnAlarm is called
  // on alarm2.
  alarm2.SetUnregisterAlarm(&alarm, &ep);
  ep.RegisterAlarm(abs_time + 1, &alarm2);
  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());

  WaitForAlarm(&ep, alarm);

  EXPECT_TRUE(alarm.was_called());
  // Make sure that alarm is called only once.
  EXPECT_EQ(1, alarm.num_called());
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  alarm.Reset();
}

// Check a couple of alarm times to make sure they're falling within a
// reasonable range.
TEST(SimpleEpollServerTest, TestRepeatAlarms) {
  EpollTestServer ep;
  TestAlarm alarm;

  int alarm_time = 20;

  // Register an alarm and make sure we wait long enough to hit it.
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  alarm.set_time_before_next_alarm(1000 * alarm_time);
  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());

  WaitForAlarm(&ep, alarm);
  // When we wake up it should be because the Alarm has been called, and has
  // registered itself to be called again.

  // Make sure the first alarm was called properly.
  EXPECT_TRUE(alarm.was_called());

  // Resetting means that the alarm is no longer a recurring alarm.  It will be
  // called once more and then stop.
  alarm.Reset();

  // Make sure the alarm is called one final time.
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  WaitForAlarm(&ep, alarm);

  EXPECT_TRUE(alarm.was_called());
  alarm.Reset();

  // The alarm was a one-time thing.  Make sure that we don't hit it again.
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_FALSE(alarm.was_called());
}

// Verify that an alarm that repeats itself in the past works properly.
TEST(SimpleEpollServerTest, TestRepeatAlarmInPast) {
  EpollTestServer ep;
  TestAlarm alarm;

  int64_t alarm_time = 20;
  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;

  // Make the alarm re-register in the past when OnAlarm is called.
  alarm.set_absolute_time(true);
  alarm.set_time_before_next_alarm(abs_time - 1000);

  // Register the alarm and make sure we wait long enough to hit it.
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  ep.RegisterAlarm(abs_time, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());

  WaitForAlarm(&ep, alarm);
  // When we wake up it should be because the Alarm has been called, and has
  // registered itself to be called again.

  // Make sure the first alarm was called properly.
  EXPECT_TRUE(alarm.was_called());

  // Resetting means that the alarm is no longer a recurring alarm.  It will be
  // called once more and then stop.
  alarm.Reset();

  // Make sure the alarm is called one final time.
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  ep.set_timeout_in_us(alarm_time * 1000 * 2);
  WaitForAlarm(&ep, alarm);

  EXPECT_TRUE(alarm.was_called());
  alarm.Reset();

  // The alarm was a one-time thing.  Make sure that we don't hit it again.
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_FALSE(alarm.was_called());
}

class EpollTestAlarms : public SimpleEpollServer {
 public:
  EpollTestAlarms() : SimpleEpollServer() {}

  inline int64_t NowInUsec() const override { return time_; }

  void CallAndReregisterAlarmEvents() override {
    recorded_now_in_us_ = NowInUsec();
    SimpleEpollServer::CallAndReregisterAlarmEvents();
  }

  void set_time(int64_t time) { time_ = time; }

  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }

 private:
  int64_t time_;
};

// Test multiple interleaving alarms to make sure they work right.
// Pattern is roughly:
// time:   15    20    30    40
// alarm:   A     B     A'    C
TEST(SimpleEpollServerTest, TestMultipleAlarms) {
  EpollTestAlarms ep;
  TestAlarm alarmA;
  TestAlarm alarmB;
  TestAlarm alarmC;

  ep.set_timeout_in_us(50 * 1000 * 2);
  alarmA.set_time_before_next_alarm(1000 * 30);
  alarmA.set_absolute_time(true);
  ep.RegisterAlarm(15 * 1000, &alarmA);
  ep.RegisterAlarm(20 * 1000, &alarmB);
  ep.RegisterAlarm(40 * 1000, &alarmC);

  ep.set_time(15 * 1000);
  ep.CallAndReregisterAlarmEvents();  // A
  EXPECT_TRUE(alarmA.was_called());
  EXPECT_FALSE(alarmB.was_called());
  EXPECT_FALSE(alarmC.was_called());
  alarmA.Reset();  // Unregister A in the future.

  ep.set_time(20 * 1000);
  ep.CallAndReregisterAlarmEvents();  // B
  EXPECT_FALSE(alarmA.was_called());
  EXPECT_TRUE(alarmB.was_called());
  EXPECT_FALSE(alarmC.was_called());
  alarmB.Reset();

  ep.set_time(30 * 1000);
  ep.CallAndReregisterAlarmEvents();  // A
  EXPECT_TRUE(alarmA.was_called());
  EXPECT_FALSE(alarmB.was_called());
  EXPECT_FALSE(alarmC.was_called());
  alarmA.Reset();

  ep.set_time(40 * 1000);
  ep.CallAndReregisterAlarmEvents();  // C
  EXPECT_FALSE(alarmA.was_called());
  EXPECT_FALSE(alarmB.was_called());
  EXPECT_TRUE(alarmC.was_called());
  alarmC.Reset();

  ep.CallAndReregisterAlarmEvents();  // None.
  EXPECT_FALSE(alarmA.was_called());
  EXPECT_FALSE(alarmB.was_called());
  EXPECT_FALSE(alarmC.was_called());
}

TEST(SimpleEpollServerTest, TestAlarmOnShutdown) {
  TestAlarm alarm1;
  {
    EpollTestServer ep;
    const int64_t now = WallTimeNowInUsec();
    ep.RegisterAlarm(now + 5000, &alarm1);
  }

  EXPECT_TRUE(alarm1.onshutdown_called());
}

// Tests that if we have multiple alarms
// OnShutdown then we handle them properly.
TEST(SimpleEpollServerTest, TestMultipleAlarmOnShutdown) {
  TestAlarm alarm1;
  TestAlarm alarm2;
  TestAlarm alarm3;
  {
    EpollTestServer ep;
    const int64_t now = WallTimeNowInUsec();
    ep.RegisterAlarm(now + 5000, &alarm1);
    ep.RegisterAlarm(now + 9000, &alarm2);
    ep.RegisterAlarm(now + 9000, &alarm3);
  }

  EXPECT_TRUE(alarm1.onshutdown_called());
  EXPECT_TRUE(alarm2.onshutdown_called());
  EXPECT_TRUE(alarm3.onshutdown_called());
}
TEST(SimpleEpollServerTest, TestMultipleAlarmUnregistrationOnShutdown) {
  TestParentAlarm tp;
  TestChildAlarm alarm1;
  TestChildAlarm alarm2;
  alarm1.set_parent(&tp);
  alarm2.set_parent(&tp);
  {
    EpollTestServer ep;
    const int64_t now = WallTimeNowInUsec();
    ep.RegisterAlarm(now + 5000, &alarm1);
    ep.RegisterAlarm(now + 9000, &alarm2);
  }

  EXPECT_TRUE(alarm1.onshutdown_called());
  EXPECT_FALSE(alarm2.onshutdown_called());
}

// Check an alarm set in the past runs right away.
TEST(SimpleEpollServerTest, TestPastAlarm) {
  EpollTestServer ep;
  TestAlarm alarm;

  // Register the alarm and make sure we wait long enough to hit it.
  ep.set_timeout_in_us(1000 * 2);
  ep.RegisterAlarm(WallTimeNowInUsec() - 1000, &alarm);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_TRUE(alarm.was_called());
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  alarm.Reset();
}

// Test Unregistering of Alarms
TEST(SimpleEpollServerTest, TestUnregisterAlarm) {
  EpollTestServer ep;
  SimpleEpollServer::AlarmRegToken temptok;

  TestAlarmUnregister alarm1;
  TestAlarmUnregister alarm2;

  ep.RegisterAlarm(WallTimeNowInUsec() + 5 * 1000, &alarm1);
  ep.RegisterAlarm(WallTimeNowInUsec() + 13 * 1000, &alarm2);

  // Unregister an alarm.
  if (alarm2.get_token(&temptok)) {
    ep.UnregisterAlarm(temptok);
  }
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  EXPECT_TRUE(alarm2.onunregistration_called());

  if (alarm1.get_token(&temptok)) {
    ep.UnregisterAlarm(temptok);
  }
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
  EXPECT_TRUE(alarm1.onunregistration_called());
}

// Test Reregistering of Alarms
TEST(SimpleEpollServerTest, TestReregisterAlarm) {
  EpollTestAlarms ep;
  SimpleEpollServer::AlarmRegToken token;

  TestAlarmUnregister alarm;
  ep.set_time(1000);
  ep.RegisterAlarm(5000, &alarm);

  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  ASSERT_TRUE(alarm.get_token(&token));
  ep.ReregisterAlarm(token, 6000);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());

  ep.set_time(5000);
  ep.set_timeout_in_us(0);
  ep.CallAndReregisterAlarmEvents();
  EXPECT_FALSE(alarm.was_called());

  ep.set_time(6000);
  ep.CallAndReregisterAlarmEvents();
  EXPECT_TRUE(alarm.was_called());
}

TEST(SimpleEpollServerTest, TestReregisterDeferredAlarm) {
  EpollTestAlarms ep;
  ep.set_timeout_in_us(0);

  TestAlarm alarm;
  TestAlarmThatRegistersAndReregistersAnotherAlarm register_alarm;
  // Register the alarm in the past so it is added as a deferred alarm.
  register_alarm.SetRegisterAndReregisterAlarm(&alarm, -500, 500, &ep);
  ep.set_time(1000);
  ep.RegisterAlarm(1000, &register_alarm);
  // Call reregister twice, first to run register_alarm and second to run any
  // scheduled deferred alarms.
  ep.CallAndReregisterAlarmEvents();
  ep.CallAndReregisterAlarmEvents();

  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  EXPECT_FALSE(alarm.was_called());

  ep.set_time(1500);
  ep.CallAndReregisterAlarmEvents();
  EXPECT_TRUE(alarm.was_called());
}

// Check if an alarm fired and got reregistered, you are able to
// unregister the second registration.
TEST(SimpleEpollServerTest, TestFiredReregisteredAlarm) {
  EpollTestAlarms ep;
  TestAlarmUnregister alarmA;

  SimpleEpollServer::AlarmRegToken first_token;
  SimpleEpollServer::AlarmRegToken second_token;
  bool found;

  ep.set_timeout_in_us(50 * 1000 * 2);
  alarmA.set_time_before_next_alarm(1000 * 30);
  alarmA.set_absolute_time(true);

  // Alarm A first fires at 15, then 30
  ep.RegisterAlarm(15 * 1000, &alarmA);

  found = alarmA.get_token(&first_token);
  EXPECT_TRUE(found);

  ep.set_time(15 * 1000);
  ep.CallAndReregisterAlarmEvents();  // A
  EXPECT_TRUE(alarmA.was_called());

  alarmA.Reset();

  found = alarmA.get_token(&second_token);
  EXPECT_TRUE(found);
  if (found) {
    ep.UnregisterAlarm(second_token);
  }

  ep.set_time(30 * 1000);
  ep.CallAndReregisterAlarmEvents();  // A

  alarmA.Reset();
}

// Here we make sure that one alarm can unregister another alarm
// in OnShutdown().
TEST(SimpleEpollServerTest, TestAlarmCanUnregistersAnotherAlarmOnShutdown) {
  TestAlarmThatUnregistersAnotherAlarm alarm1;
  TestAlarm alarm2;
  {
    EpollTestServer ep;
    // Register two alarms and make alarm1 is placed in queue in front of alarm2
    // so that when the queue is cleared, alarm1 is processed first.
    const int64_t now = WallTimeNowInUsec();
    ep.RegisterAlarm(now + 5000, &alarm1);
    ep.RegisterAlarm(now + 9000, &alarm2);
    alarm1.SetUnregisterAlarm(&alarm2, &ep);
    EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
  }
}

class TestAlarmRegisterAnotherAlarmShutdown : public TestAlarmUnregister {
 public:
  TestAlarmRegisterAnotherAlarmShutdown(EpollAlarmCallbackInterface* alarm2,
                                        int64_t when)
      : alarm2_(alarm2), when_(when) {}
  void OnShutdown(SimpleEpollServer* eps) override {
    TestAlarmUnregister::OnShutdown(eps);
    eps->RegisterAlarm(when_, alarm2_);
  }

 private:
  EpollAlarmCallbackInterface* alarm2_;
  int64_t when_;
};

// This tests that alarm registers another alarm when shutting down.
// The two cases are: new alarm comes before and after the alarm being
// notified by OnShutdown()
TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownBeforeSelf) {
  TestAlarm alarm2;
  int64_t alarm_time = WallTimeNowInUsec() + 5000;
  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time - 1000);
  {
    EpollTestAlarms ep;
    ep.RegisterAlarm(alarm_time, &alarm1);
  }
  EXPECT_TRUE(alarm1.onshutdown_called());
  EXPECT_FALSE(alarm2.onshutdown_called());
}

TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownAfterSelf) {
  TestAlarm alarm2;
  int64_t alarm_time = WallTimeNowInUsec() + 5000;
  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time + 1000);
  {
    EpollTestAlarms ep;
    ep.RegisterAlarm(alarm_time, &alarm1);
  }
  EXPECT_TRUE(alarm1.onshutdown_called());
  EXPECT_TRUE(alarm2.onshutdown_called());
}

TEST(SimpleEpollServerTest, TestWrite) {
  SimpleEpollServer ep;
  ep.set_timeout_in_us(1);
  char data[kPageSize] = {0};

  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }
  int read_fd = pipe_fds[0];
  int write_fd = pipe_fds[1];

  RecordingCB recording_cb;
  const Recorder* recorder = recording_cb.recorder();
  const std::vector<RecordEntry>* records = recorder->records();

  // Register to listen to write events.
  ep.RegisterFD(write_fd, &recording_cb, EPOLLOUT | O_NONBLOCK);
  // At this point the recorder should have the creation and registration
  // events.
  EXPECT_EQ(2u, records->size());

  // Fill up the pipe.
  int written = 1;
  for (int i = 0; i < 17 && written > 0; ++i) {
    written = write(write_fd, &data, kPageSize);
  }
  EXPECT_LT(written, 0);

  // There should be no new events as the pipe is not available for writing.
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(2u, records->size());

  // Now read data from the pipe to make it writable again.  This time the
  // we should get an EPOLLOUT event.
  int size = read(read_fd, &data, kPageSize);
  EXPECT_EQ(kPageSize, size);
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(3u, records->size());

  // Now unsubscribe from writable events (which adds a modification record)
  // and wait to verify that no event records are added.
  ep.StopWrite(write_fd);
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(4u, records->size());

  // We had the right number of events all along. Make sure they were actually
  // the right events.
  Recorder tmp;
  tmp.Record(&recording_cb, CREATION, 0, 0);
  tmp.Record(&recording_cb, REGISTRATION, write_fd, EPOLLOUT | O_NONBLOCK);
  tmp.Record(&recording_cb, EVENT, write_fd, EPOLLOUT);
  tmp.Record(&recording_cb, MODIFICATION, write_fd, O_NONBLOCK);

  EXPECT_TRUE(recorder->IsEqual(&tmp));
  ep.UnregisterFD(write_fd);

  close(read_fd);
  close(write_fd);
}

TEST(SimpleEpollServerTest, TestReadWrite) {
  SimpleEpollServer ep;
  ep.set_timeout_in_us(1);
  char data[kPageSize] = {0};

  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }
  int read_fd = pipe_fds[0];
  int write_fd = pipe_fds[1];

  RecordingCB recording_cb;
  const Recorder* recorder = recording_cb.recorder();
  const std::vector<RecordEntry>* records = recorder->records();

  // Register to listen to read and write events.
  ep.RegisterFDForReadWrite(read_fd, &recording_cb);
  // At this point the recorder should have the creation and registration
  // events.
  EXPECT_EQ(2u, records->size());

  int written = write(write_fd, &data, kPageSize);
  EXPECT_EQ(kPageSize, written);

  ep.WaitForEventsAndExecuteCallbacks();
  ep.UnregisterFD(read_fd);

  close(read_fd);
  close(write_fd);
}

TEST(SimpleEpollServerTest, TestMultipleFDs) {
  SimpleEpollServer ep;
  ep.set_timeout_in_us(1);
  char data = 'x';

  int pipe_one[2];
  if (pipe(pipe_one) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }
  int pipe_two[2];
  if (pipe(pipe_two) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }

  RecordingCB recording_cb_one;
  const Recorder* recorder_one = recording_cb_one.recorder();
  const std::vector<RecordEntry>* records_one = recorder_one->records();

  RecordingCB recording_cb_two;
  const Recorder* recorder_two = recording_cb_two.recorder();
  const std::vector<RecordEntry>* records_two = recorder_two->records();

  // Register to listen to read events for both pipes
  ep.RegisterFDForRead(pipe_one[0], &recording_cb_one);
  ep.RegisterFDForRead(pipe_two[0], &recording_cb_two);

  EXPECT_EQ(2u, records_one->size());
  EXPECT_EQ(2u, records_two->size());

  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(3u, records_one->size());
  EXPECT_EQ(2u, records_two->size());

  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(3u, records_one->size());
  EXPECT_EQ(3u, records_two->size());

  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(4u, records_one->size());
  EXPECT_EQ(4u, records_two->size());

  ep.WaitForEventsAndExecuteCallbacks();
  ep.UnregisterFD(pipe_one[0]);
  ep.UnregisterFD(pipe_two[0]);
  close(pipe_one[0]);
  close(pipe_one[1]);
  close(pipe_two[0]);
  close(pipe_two[1]);
}

// Check that the SimpleEpollServer calls OnShutdown for any registered FDs.
TEST(SimpleEpollServerTest, TestFDOnShutdown) {
  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }
  int read_fd = pipe_fds[0];
  int write_fd = pipe_fds[1];

  RecordingCB recording_cb1;
  RecordingCB recording_cb2;
  const Recorder* recorder1 = recording_cb1.recorder();
  const Recorder* recorder2 = recording_cb2.recorder();

  {
    SimpleEpollServer ep;
    ep.set_timeout_in_us(1);

    // Register to listen to write events.
    ep.RegisterFD(write_fd, &recording_cb1, EPOLLOUT | O_NONBLOCK);
    ep.RegisterFD(read_fd, &recording_cb2, EPOLLIN | O_NONBLOCK);
  }

  // Make sure OnShutdown was called for both callbacks.
  Recorder write_recorder;
  write_recorder.Record(&recording_cb1, CREATION, 0, 0);
  write_recorder.Record(&recording_cb1, REGISTRATION, write_fd,
                        EPOLLOUT | O_NONBLOCK);
  write_recorder.Record(&recording_cb1, UNREGISTRATION, write_fd, false);
  write_recorder.Record(&recording_cb1, SHUTDOWN, write_fd, 0);
  EXPECT_TRUE(recorder1->IsEqual(&write_recorder));

  Recorder read_recorder;
  read_recorder.Record(&recording_cb2, CREATION, 0, 0);
  read_recorder.Record(&recording_cb2, REGISTRATION, read_fd,
                       EPOLLIN | O_NONBLOCK);
  read_recorder.Record(&recording_cb2, UNREGISTRATION, read_fd, false);
  read_recorder.Record(&recording_cb2, SHUTDOWN, read_fd, 0);
  EXPECT_TRUE(recorder2->IsEqual(&read_recorder));

  close(read_fd);
  close(write_fd);
}

class UnregisterCB : public EpollCallbackInterface {
 public:
  explicit UnregisterCB(int fd)
      : eps_(nullptr), fd_(fd), onshutdown_called_(false) {}

  ~UnregisterCB() override {}

  void OnShutdown(SimpleEpollServer* /*eps*/, int fd) override {
    eps_->UnregisterFD(fd_);
    eps_->UnregisterFD(fd);
    onshutdown_called_ = true;
    eps_ = nullptr;
  }

  void set_epollserver(SimpleEpollServer* eps) { eps_ = eps; }
  bool onshutdown_called() { return onshutdown_called_; }

  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {}
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}

  std::string Name() const override { return "UnregisterCB"; }

 protected:
  SimpleEpollServer* eps_;
  int fd_;
  bool onshutdown_called_;
};

// Check that unregistering fds in OnShutdown works cleanly.
TEST(SimpleEpollServerTest, TestUnregisteringFDsOnShutdown) {
  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }
  int read_fd = pipe_fds[0];
  int write_fd = pipe_fds[1];

  UnregisterCB unreg_cb1(read_fd);
  UnregisterCB unreg_cb2(write_fd);

  {
    SimpleEpollServer ep;
    ep.set_timeout_in_us(1);

    unreg_cb1.set_epollserver(&ep);
    unreg_cb2.set_epollserver(&ep);

    // Register to listen to write events.
    ep.RegisterFD(write_fd, &unreg_cb1, EPOLLOUT | O_NONBLOCK);
    ep.RegisterFD(read_fd, &unreg_cb2, EPOLLIN | O_NONBLOCK);
  }

  // Make sure at least one onshutdown was called.
  EXPECT_TRUE(unreg_cb1.onshutdown_called() || unreg_cb2.onshutdown_called());
  // Make sure that both onshutdowns were not called.
  EXPECT_TRUE(
      !(unreg_cb1.onshutdown_called() && unreg_cb2.onshutdown_called()));

  close(read_fd);
  close(write_fd);
}

TEST(SimpleEpollServerTest, TestFDsAndAlarms) {
  SimpleEpollServer ep;
  ep.set_timeout_in_us(5);
  char data = 'x';

  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }

  RecordingCB recording_cb;
  const Recorder* recorder = recording_cb.recorder();
  const std::vector<RecordEntry>* records = recorder->records();

  TestAlarm alarm;

  ep.RegisterFDForRead(pipe_fds[0], &recording_cb);

  EXPECT_EQ(2u, records->size());
  EXPECT_FALSE(alarm.was_called());

  // Write to the pipe and set a longish alarm so we get a read event followed
  // by an alarm event.
  int written = write(pipe_fds[1], &data, 1);
  EXPECT_EQ(1, written);
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(3u, records->size());
  EXPECT_FALSE(alarm.was_called());
  ep.RegisterAlarm(WallTimeNowInUsec() + 1000, &alarm);
  WaitForAlarm(&ep, alarm);
  EXPECT_EQ(3u, records->size());
  EXPECT_TRUE(alarm.was_called());
  alarm.Reset();

  // Now set a short alarm so the alarm and the read event are called together.
  ep.RegisterAlarm(WallTimeNowInUsec(), &alarm);
  written = write(pipe_fds[1], &data, 1);
  EXPECT_EQ(1, written);
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_TRUE(alarm.was_called());
  EXPECT_EQ(4u, records->size());

  ep.UnregisterFD(pipe_fds[0]);

  close(pipe_fds[0]);
  close(pipe_fds[1]);
}

class EpollReader : public EpollCallbackInterface {
 public:
  explicit EpollReader(int len)
      : len_(0), expected_len_(len), done_reading_(false) {
    memset(&buf_, 0, kMaxBufLen);
  }

  ~EpollReader() override {}

  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}

  void OnModification(int /*fd*/, int /*event_mask*/) override {}

  void OnEvent(int fd, EpollEvent* event) override {
    if (event->in_events & EPOLLIN) {
      len_ += read(fd, &buf_ + len_, kMaxBufLen - len_);
    }

    // If we have finished reading...
    if (event->in_events & EPOLLHUP) {
      CHECK_EQ(len_, expected_len_);
      done_reading_ = true;
    }
  }

  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
    // None of the current tests involve having active callbacks when the
    // server shuts down.
    EPOLL_LOG(FATAL);
  }

  std::string Name() const override { return "EpollReader"; }

  // Returns true if the data in buf is the same as buf_, false otherwise.
  bool CheckOutput(char* buf, int len) {
    if (len != len_) {
      return false;
    }
    return !memcmp(buf, buf_, len);
  }

  bool done_reading() { return done_reading_; }

 protected:
  int len_;
  int expected_len_;
  char buf_[kMaxBufLen];
  bool done_reading_;
};

void TestPipe(char* test_message, int len) {
  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe failed()";
  }
  int reader_pipe = pipe_fds[0];
  int writer_pipe = pipe_fds[1];
  int child_pid;
  memset(test_message, 'x', len);

  switch (child_pid = fork()) {
    case 0: {  // Child will send message.
      const char* message = test_message;
      int size;
      close(reader_pipe);
      while ((size = write(writer_pipe, message, len)) > 0) {
        message += size;
        len -= size;
        if (len == 0) {
          break;
        }
      }
      if (len > 0) {
        EPOLL_PLOG(FATAL) << "write() failed";
      }
      close(writer_pipe);

      _exit(0);
    }
    case -1:
      EPOLL_PLOG(FATAL) << "fork() failed";
      break;
    default: {  // Parent will receive message.
      close(writer_pipe);
      auto ep = std::make_unique<SimpleEpollServer>();
      ep->set_timeout_in_us(1);
      EpollReader reader(len);
      ep->RegisterFD(reader_pipe, &reader, EPOLLIN);

      int64_t start_ms = WallTimeNowInUsec() / 1000;
      // Loop until we're either done reading, or have waited ~10 us.
      while (!reader.done_reading() &&
             (WallTimeNowInUsec() / 1000 - start_ms) < 10000) {
        ep->WaitForEventsAndExecuteCallbacks();
      }
      ep->UnregisterFD(reader_pipe);
      CHECK(reader.CheckOutput(test_message, len));
      break;
    }
  }

  close(reader_pipe);
  close(writer_pipe);
}

TEST(SimpleEpollServerTest, TestSmallPipe) {
  char buf[kMaxBufLen];
  TestPipe(buf, 10);
}

TEST(SimpleEpollServerTest, TestLargePipe) {
  char buf[kMaxBufLen];
  TestPipe(buf, kMaxBufLen);
}

// Tests RegisterFDForRead as well as StopRead.
TEST(SimpleEpollServerTest, TestRead) {
  SimpleEpollServer ep;
  ep.set_timeout_in_us(1);
  int len = 1;

  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }
  int read_fd = pipe_fds[0];
  int write_fd = pipe_fds[1];

  auto reader = std::make_unique<EpollReader>(len);

  // Check that registering a FD for read alerts us when there is data to be
  // read.
  ep.RegisterFDForRead(read_fd, reader.get());
  char data = 'a';
  int size = write(write_fd, &data, 1);
  EXPECT_EQ(1, size);
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_TRUE(reader->CheckOutput(&data, len));

  // Remove the callback for read events, write to the pipe and make sure that
  // we did not read more data.
  ep.StopRead(read_fd);
  size = write(write_fd, &data, len);
  EXPECT_EQ(1, size);
  // The wait will return after timeout.
  ep.WaitForEventsAndExecuteCallbacks();
  EXPECT_TRUE(reader->CheckOutput(&data, len));
  ep.UnregisterFD(read_fd);

  close(read_fd);
  close(write_fd);
}

class EdgeTriggerCB : public EpollCallbackInterface {
 public:
  EdgeTriggerCB(int read_size, int write_size, char write_char, char peer_char)
      : eps_(nullptr),
        read_buf_(read_size),
        write_buf_(write_size, write_char),
        peer_char_(peer_char) {
    Reset();
  }

  ~EdgeTriggerCB() override {}

  void Reset() {
    CHECK(eps_ == nullptr);
    bytes_read_ = 0;
    bytes_written_ = 0;
    can_read_ = false;
    will_read_ = false;
    can_write_ = false;
    will_write_ = false;
    read_closed_ = false;
    write_closed_ = false;
  }

  void ResetByteCounts() { bytes_read_ = bytes_written_ = 0; }

  void set_will_read(bool will_read) { will_read_ = will_read; }

  void set_will_write(bool will_write) { will_write_ = will_write; }

  bool can_write() const { return can_write_; }

  int bytes_read() const { return bytes_read_; }

  int bytes_written() const { return bytes_written_; }

  void OnRegistration(SimpleEpollServer* eps, int fd, int event_mask) override {
    EXPECT_TRUE(eps_ == nullptr);
    eps_ = eps;
    Initialize(fd, event_mask);
  }

  void OnModification(int fd, int event_mask) override {
    EXPECT_TRUE(eps_ != nullptr);
    if (event_mask & EPOLLET) {
      Initialize(fd, event_mask);
    } else {
      eps_->SetFDNotReady(fd);
    }
  }

  void OnEvent(int fd, EpollEvent* event) override {
    const int event_mask = event->in_events;
    if (event_mask & (EPOLLHUP | EPOLLERR)) {
      write_closed_ = true;
      return;
    }
    if (will_read_ && event_mask & EPOLLIN) {
      EXPECT_FALSE(read_closed_);
      int read_size = read_buf_.size();
      memset(&read_buf_[0], 0, read_size);
      int len = recv(fd, &read_buf_[0], read_size, MSG_DONTWAIT);
      // Update the readiness states
      can_read_ = (len == read_size);

      if (len > 0) {
        bytes_read_ += len;
        EPOLL_VLOG(1) << "fd: " << fd << ", read " << len
                      << ", total: " << bytes_read_;
        // Now check the bytes read
        EXPECT_TRUE(CheckReadBuffer(len));
      } else if (len < 0) {
        EPOLL_VLOG(1) << "fd: " << fd << " read hit EAGAIN";
        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
        can_read_ = false;
      } else {
        read_closed_ = true;
      }
    }
    if (will_write_ && event_mask & EPOLLOUT) {
      // Write side close/full close can only detected by EPOLLHUP, which is
      // caused by EPIPE.
      EXPECT_FALSE(write_closed_);
      int write_size = write_buf_.size();
      int len = send(fd, &write_buf_[0], write_size, MSG_DONTWAIT);
      can_write_ = (len == write_size);
      if (len > 0) {
        bytes_written_ += len;
        EPOLL_VLOG(1) << "fd: " << fd << ", write " << len
                      << ", total: " << bytes_written_;
      } else {
        EPOLL_VLOG(1) << "fd: " << fd << " write hit EAGAIN";
        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
        can_write_ = false;
      }
    }
    // Since we can only get on the ready list once, wait till we confirm both
    // read and write side continuation state and set the correct event mask
    // for the ready list.
    event->out_ready_mask = can_read_ ? static_cast<int>(EPOLLIN) : 0;
    if (can_write_) {
      event->out_ready_mask |= EPOLLOUT;
    }
  }

  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {
    EXPECT_TRUE(eps_ != nullptr);
    eps_ = nullptr;
  }

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
    // None of the current tests involve having active callbacks when the
    // server shuts down.
    EPOLL_LOG(FATAL);
  }

  std::string Name() const override { return "EdgeTriggerCB"; }

 private:
  SimpleEpollServer* eps_;
  std::vector<char> read_buf_;
  int bytes_read_;
  std::vector<char> write_buf_;
  int bytes_written_;
  char peer_char_;  // The char we expected to read.
  bool can_read_;
  bool will_read_;
  bool can_write_;
  bool will_write_;
  bool read_closed_;
  bool write_closed_;

  void Initialize(int fd, int event_mask) {
    CHECK(eps_);
    can_read_ = can_write_ = false;
    if (event_mask & EPOLLET) {
      int events = 0;
      if (event_mask & EPOLLIN) {
        events |= EPOLLIN;
        can_read_ = true;
      }
      if (event_mask & EPOLLOUT) {
        events |= EPOLLOUT;
        can_write_ = true;
      }
      eps_->SetFDReady(fd, events);
    }
  }

  bool CheckReadBuffer(int len) const {
    for (int i = 0; i < len; ++i) {
      if (peer_char_ != read_buf_[i]) {
        return false;
      }
    }
    return true;
  }
};

// Test adding and removing from the ready list.
TEST(SimpleEpollServerTest, TestReadyList) {
  SimpleEpollServer ep;
  int pipe_fds[2];
  if (pipe(pipe_fds) < 0) {
    EPOLL_PLOG(FATAL) << "pipe() failed";
  }

  // Just use any CB will do, since we never wait on epoll events.
  EdgeTriggerCB reader1(0, 0, 0, 0);
  EdgeTriggerCB reader2(0, 0, 0, 0);

  ep.RegisterFD(pipe_fds[0], &reader1, EPOLLIN);
  ep.RegisterFD(pipe_fds[1], &reader2, EPOLLOUT);

  // Adding fds that are registered with eps
  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));

  ep.SetFDReady(pipe_fds[0], EPOLLIN);
  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
  EXPECT_EQ(1u, ep.ReadyListSize());
  ep.SetFDReady(pipe_fds[1], EPOLLOUT);
  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
  EXPECT_EQ(2u, ep.ReadyListSize());

  // Now check that SetFDNotReady doesn't affect other fds
  ep.SetFDNotReady(pipe_fds[0]);
  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
  EXPECT_EQ(1u, ep.ReadyListSize());

  ep.UnregisterFD(pipe_fds[0]);
  ep.UnregisterFD(pipe_fds[1]);
  EXPECT_EQ(0u, ep.ReadyListSize());

  // Now try adding them when they are not registered, and it shouldn't work.
  ep.SetFDReady(pipe_fds[0], EPOLLIN);
  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
  EXPECT_EQ(0u, ep.ReadyListSize());

  close(pipe_fds[0]);
  close(pipe_fds[1]);
}

class EPSWaitThread : public EpollThread {
 public:
  explicit EPSWaitThread(SimpleEpollServer* eps)
      : EpollThread("EPSWait"), eps_(eps), done_(false) {}

  void Run() override { eps_->WaitForEventsAndExecuteCallbacks(); }

  bool done() { return done_; }

 private:
  SimpleEpollServer* eps_;
  bool done_;
};

TEST(EpollServerTest, TestWake) {
  SimpleEpollServer eps;
  eps.set_timeout_in_us(-1);
  EPSWaitThread eps_thread(&eps);
  eps_thread.Start();

  EXPECT_FALSE(eps_thread.done());
  eps.Wake();
  eps_thread.Join();
}

class UnRegisterWhileProcessingCB : public EpollCallbackInterface {
 public:
  explicit UnRegisterWhileProcessingCB(int fd) : eps_(nullptr), fd_(fd) {}

  ~UnRegisterWhileProcessingCB() override {}

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}

  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
    // This should cause no problems.
    eps_->UnregisterFD(fd_);
  }
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
  std::string Name() const override { return "UnRegisterWhileProcessingCB"; }

 protected:
  SimpleEpollServer* eps_;
  int fd_;
};

class RegisterWhileProcessingCB : public EpollCallbackInterface {
 public:
  RegisterWhileProcessingCB(int fd, EpollCallbackInterface* cb)
      : eps_(nullptr), fd_(fd), cb_(cb) {}

  ~RegisterWhileProcessingCB() override {}

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}

  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
    // This should cause no problems.
    eps_->RegisterFDForReadWrite(fd_, cb_);
  }
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
  std::string Name() const override { return "RegisterWhileProcessingCB"; }

 protected:
  SimpleEpollServer* eps_;
  int fd_;
  EpollCallbackInterface* cb_;
};

// Nothing bad should happen when we do this. We're -only-
// testing that nothing bad occurs in this test.
TEST(SimpleEpollServerTest, NothingBadWhenUnRegisteringFDWhileProcessingIt) {
  UnRegisterWhileProcessingCB cb(0);
  {
    FakeSimpleEpollServer epoll_server;
    cb.set_epoll_server(&epoll_server);
    epoll_server.RegisterFDForReadWrite(0, &cb);
    epoll_event ee;
    ee.data.fd = 0;
    epoll_server.AddEvent(0, ee);
    epoll_server.AdvanceBy(1);
    epoll_server.WaitForEventsAndExecuteCallbacks();
  }
}

//
// testing that nothing bad occurs in this test.
TEST(SimpleEpollServerTest,
     NoEventsDeliveredForFdsOfUnregisteredCBsWithReRegdFD) {
  // events: fd0, fd1, fd2
  // fd0 -> unreg fd2
  // fd1 -> reg fd2
  // fd2 -> no event should be seen
  RecordingCB recorder_cb;
  UnRegisterWhileProcessingCB unreg_cb(-3);
  RegisterWhileProcessingCB reg_other_cb(-3, &recorder_cb);
  {
    FakeSimpleEpollServer epoll_server;
    unreg_cb.set_epoll_server(&epoll_server);
    reg_other_cb.set_epoll_server(&epoll_server);
    epoll_server.RegisterFDForReadWrite(-1, &unreg_cb);
    epoll_server.RegisterFDForReadWrite(-2, &reg_other_cb);
    epoll_server.RegisterFDForReadWrite(-3, &recorder_cb);

    epoll_event ee;
    ee.events = EPOLLIN;  // asserted for all events for this test.

    // Note that these events are in 'backwards' order in terms of time.
    // Currently, the SimpleEpollServer code invokes the CBs from last delivered
    // to first delivered, so this is to be sure that we invoke the CB for -1
    // before -2, before -3.
    ee.data.fd = -1;
    epoll_server.AddEvent(2, ee);
    ee.data.fd = -2;
    epoll_server.AddEvent(1, ee);
    ee.data.fd = -3;
    epoll_server.AddEvent(0, ee);

    epoll_server.AdvanceBy(5);
    epoll_server.WaitForEventsAndExecuteCallbacks();
  }

  Recorder correct_recorder;
  correct_recorder.Record(&recorder_cb, CREATION, 0, 0);
  correct_recorder.Record(&recorder_cb, REGISTRATION, -3, EPOLLIN | EPOLLOUT);
  correct_recorder.Record(&recorder_cb, UNREGISTRATION, -3, 0);
  correct_recorder.Record(&recorder_cb, REGISTRATION, -3, EPOLLIN | EPOLLOUT);
  correct_recorder.Record(&recorder_cb, SHUTDOWN, -3, 0);

  EXPECT_TRUE(correct_recorder.IsEqual(recorder_cb.recorder()));
}

class ReRegWhileReadyListOnEvent : public EpollCallbackInterface {
 public:
  explicit ReRegWhileReadyListOnEvent(int /*fd*/) : eps_(nullptr) {}

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}

  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int fd, EpollEvent* /*event_mask*/) override {
    // This should cause no problems.
    eps_->UnregisterFD(fd);
    eps_->RegisterFDForReadWrite(fd, this);
    eps_->UnregisterFD(fd);
  }
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
  std::string Name() const override { return "ReRegWhileReadyListOnEvent"; }

 protected:
  SimpleEpollServer* eps_;
};

// Nothing bad should happen when we do this. We're -only-
// testing that nothing bad occurs in this test.
TEST(SimpleEpollServerTest,
     NothingBadWhenReRegisteringFDWhileProcessingFromReadyList) {
  ReRegWhileReadyListOnEvent cb(0);
  {
    FakeSimpleEpollServer epoll_server;
    cb.set_epoll_server(&epoll_server);
    epoll_server.RegisterFDForReadWrite(0, &cb);
    epoll_event ee;
    ee.data.fd = 0;
    epoll_server.AddEvent(0, ee);
    epoll_server.AdvanceBy(1);
    epoll_server.WaitForEventsAndExecuteCallbacks();
  }
}

class UnRegEverythingReadyListOnEvent : public EpollCallbackInterface {
 public:
  UnRegEverythingReadyListOnEvent() : eps_(nullptr), fd_(0), fd_range_(0) {}

  void set_fd(int fd) { fd_ = fd; }
  void set_fd_range(int fd_range) { fd_range_ = fd_range; }
  void set_num_called(int* num_called) { num_called_ = num_called; }

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}

  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
  void OnRegistration(SimpleEpollServer* eps, int fd,
                      int /*event_mask*/) override {
    eps->SetFDReady(fd, EPOLLIN);
  }
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
    // This should cause no problems.
    CHECK(num_called_ != nullptr);
    ++(*num_called_);
    // Note that we're iterating from -fd_range + 1 -> 0.
    // We do this because there is an FD installed into the
    // epollserver somewhere in the low numbers.
    // Using negative FD numbers (which are guaranteed to not
    // exist in the epoll-server) ensures that we will not
    // come in conflict with the preexisting FD.
    for (int i = -fd_range_ + 1; i <= 0; ++i) {
      eps_->UnregisterFD(i);
    }
  }
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
  std::string Name() const override {
    return "UnRegEverythingReadyListOnEvent";
  }

 protected:
  SimpleEpollServer* eps_;
  int fd_;
  int fd_range_;
  int* num_called_;
};

TEST(SimpleEpollServerTest,
     NothingBadWhenUnRegisteredWhileProcessingFromReadyList) {
  const size_t kNumCallbacks = 32u;
  UnRegEverythingReadyListOnEvent callbacks[kNumCallbacks];
  int num_called = 0;
  {
    FakeSimpleEpollServer epoll_server;
    for (size_t i = 0; i < kNumCallbacks; ++i) {
      callbacks[i].set_fd(-i);
      callbacks[i].set_fd_range(kNumCallbacks);
      callbacks[i].set_num_called(&num_called);
      callbacks[i].set_epoll_server(&epoll_server);
      epoll_server.RegisterFDForReadWrite(0, &callbacks[i]);
      epoll_event ee;
      ee.data.fd = -i;
      epoll_server.AddEvent(0, ee);
    }
    epoll_server.AdvanceBy(1);
    epoll_server.WaitForEventsAndExecuteCallbacks();
    epoll_server.WaitForEventsAndExecuteCallbacks();
  }
  EXPECT_EQ(1, num_called);
}

TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithNothingInList) {
  FakeSimpleEpollServer epoll_server;
  epoll_server.VerifyReadyList();
}

TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithStuffInLists) {
  FakeSimpleEpollServer epoll_server;
  epoll_server.VerifyReadyList();
}

TEST(SimpleEpollServerTest,
     ApproximateNowInUsAccurateOutideOfWaitForEventsAndExecuteCallbacks) {
  FakeSimpleEpollServer epoll_server;
  epoll_server.AdvanceBy(1232);
  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
  epoll_server.AdvanceBy(1111);
  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
}

class ApproximateNowInUsecTestCB : public EpollCallbackInterface {
 public:
  ApproximateNowInUsecTestCB() : feps_(nullptr), called_(false) {}

  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
    EXPECT_EQ(feps_->ApproximateNowInUsec(), feps_->NowInUsec());
    feps_->AdvanceBy(1111);
    EXPECT_EQ(1 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
    feps_->AdvanceBy(1111);
    EXPECT_EQ(2 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
    called_ = true;
  }
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
  std::string Name() const override { return "ApproximateNowInUsecTestCB"; }

  void set_fakeepollserver(FakeSimpleEpollServer* feps) { feps_ = feps; }
  bool called() const { return called_; }

 protected:
  FakeSimpleEpollServer* feps_;
  bool called_;
};

TEST(SimpleEpollServerTest,
     ApproximateNowInUsApproximateInsideOfWaitForEventsAndExecuteCallbacks) {
  int dummy_fd = 11111;
  ApproximateNowInUsecTestCB aniutcb;
  {
    FakeSimpleEpollServer epoll_server;
    aniutcb.set_fakeepollserver(&epoll_server);

    epoll_server.RegisterFD(dummy_fd, &aniutcb, EPOLLIN);
    epoll_event ee;
    ee.data.fd = dummy_fd;
    ee.events = EPOLLIN;
    epoll_server.AddEvent(10242, ee);
    epoll_server.set_timeout_in_us(-1);
    epoll_server.AdvanceByAndWaitForEventsAndExecuteCallbacks(20000);
    EXPECT_TRUE(aniutcb.called());
  }
}

// A mock epoll server that also simulates kernel delay in scheduling epoll
// events.
class FakeEpollServerWithDelay : public FakeSimpleEpollServer {
 public:
  FakeEpollServerWithDelay() : FakeSimpleEpollServer(), delay(0) {}

  int delay;

 protected:
  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
                      int timeout_in_ms) override {
    int out = FakeSimpleEpollServer::epoll_wait_impl(epfd, events, max_events,
                                                     timeout_in_ms);
    AdvanceBy(delay);
    return out;
  }
};

// A callback that records the epoll event's delay.
class RecordDelayOnEvent : public EpollCallbackInterface {
 public:
  RecordDelayOnEvent() : last_delay(-1), eps_(nullptr) {}

  ~RecordDelayOnEvent() override {}

  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}

  std::string Name() const override { return "RecordDelayOnEvent"; }

  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
                      int /*event_mask*/) override {}
  void OnModification(int /*fd*/, int /*event_mask*/) override {}
  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
    last_delay = eps_->LastDelayInUsec();
  }
  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}

  int64_t last_delay;

 protected:
  SimpleEpollServer* eps_;
};

// Tests that an epoll callback sees the correct delay for its event when it
// calls LastDelayInUsec().
TEST(EpollServerTest, TestLastDelay) {
  RecordDelayOnEvent cb;
  FakeEpollServerWithDelay epoll_server;

  cb.set_epoll_server(&epoll_server);

  epoll_server.RegisterFDForReadWrite(0, &cb);
  epoll_event ee;
  ee.data.fd = 0;

  // Inject delay, and confirm that it's reported.
  epoll_server.set_timeout_in_us(5000);
  epoll_server.delay = 6000;
  epoll_server.AddEvent(0, ee);
  epoll_server.AdvanceBy(1);
  epoll_server.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(cb.last_delay, 1000);

  // Fire an event before the timeout ends, and confirm that reported delay
  // isn't negative.
  epoll_server.set_timeout_in_us(5000);
  epoll_server.delay = 0;
  epoll_server.AddEvent(0, ee);
  epoll_server.AdvanceBy(1);
  epoll_server.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(cb.last_delay, 0);

  // Wait forever until an event fires, and confirm there's no reported delay.
  epoll_server.set_timeout_in_us(-1);
  epoll_server.delay = 6000;
  epoll_server.AddEvent(0, ee);
  epoll_server.AdvanceBy(1);
  epoll_server.WaitForEventsAndExecuteCallbacks();
  EXPECT_EQ(cb.last_delay, 0);
}

TEST(SimpleEpollServerAlarmTest, TestShutdown) {
  std::unique_ptr<SimpleEpollServer> eps(new SimpleEpollServer);
  EpollAlarm alarm1;
  EpollAlarm alarm2;

  eps->RegisterAlarmApproximateDelta(10000000, &alarm1);
  eps->RegisterAlarmApproximateDelta(10000000, &alarm2);

  alarm2.UnregisterIfRegistered();
  EXPECT_FALSE(alarm2.registered());
  eps = nullptr;

  EXPECT_FALSE(alarm1.registered());
}

TEST(SimpleEpollServerAlarmTest, TestUnregister) {
  SimpleEpollServer eps;
  EpollAlarm alarm;

  eps.RegisterAlarmApproximateDelta(10000000, &alarm);
  EXPECT_TRUE(alarm.registered());

  alarm.UnregisterIfRegistered();
  EXPECT_FALSE(alarm.registered());

  alarm.UnregisterIfRegistered();
  EXPECT_FALSE(alarm.registered());
}

TEST(SimpleEpollServerAlarmTest, TestUnregisterOnDestruction) {
  EpollTestServer eps;
  std::unique_ptr<EpollAlarm> alarm(new EpollAlarm());
  EpollAlarm* alarm_ptr = alarm.get();

  eps.RegisterAlarmApproximateDelta(10000000, alarm.get());
  EXPECT_TRUE(eps.ContainsAlarm(alarm_ptr));
  alarm = nullptr;
  EXPECT_EQ(0u, eps.GetNumPendingAlarmsForTest());
}

TEST(SimpleEpollServerAlarmTest, TestUnregisterOnAlarm) {
  EpollTestServer eps;
  EpollAlarm alarm;

  eps.RegisterAlarmApproximateDelta(1, &alarm);
  EXPECT_TRUE(eps.ContainsAlarm(&alarm));

  while (alarm.registered()) {
    eps.WaitForEventsAndExecuteCallbacks();
  }
  EXPECT_FALSE(eps.ContainsAlarm(&alarm));
}

TEST(SimpleEpollServerAlarmTest, TestReregisterAlarm) {
  EpollTestAlarms ep;

  EpollAlarm alarm;
  ep.set_time(1000);
  ep.RegisterAlarm(5000, &alarm);

  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
  alarm.ReregisterAlarm(6000);
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());

  ep.set_time(5000);
  ep.set_timeout_in_us(0);
  ep.CallAndReregisterAlarmEvents();
  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());

  ep.set_time(6000);
  ep.CallAndReregisterAlarmEvents();
  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
}

TEST(SimpleEpollServerAlarmTest, TestThatSameAlarmCanNotBeRegisteredTwice) {
  TestAlarm alarm;
  SimpleEpollServer epoll_server;
  epoll_server.RegisterAlarm(1, &alarm);
  EXPECT_EPOLL_BUG(epoll_server.RegisterAlarm(1, &alarm),
                   "Alarm already exists");
}

}  // namespace

}  // namespace test

}  // namespace epoll_server
