// 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 "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_ptr_util.h"
#include "quiche/epoll_server/platform/api/epoll_test.h"
#include "quiche/epoll_server/platform/api/epoll_thread.h"
#include "quiche/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];
      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 = 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_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
