// 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 "net/third_party/quiche/src/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 "net/third_party/quiche/src/epoll_server/fake_simple_epoll_server.h"
#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_address_test_utils.h"
#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_expect_bug.h"
#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_ptr_util.h"
#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_test.h"
#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_thread.h"
#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_time.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
};

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


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

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];
      read(fd, &buf, kLength);
    }
  }

  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(1, 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());

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

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

  write(pipe_one[1], &data, 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 = EpollMakeUnique<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 = EpollMakeUnique<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) 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
