Project import generated by Copybara.

PiperOrigin-RevId: 243658601
Change-Id: I2522d468d82c86f8f222cf0e70114d6a9ca2b78c
diff --git a/epoll_server/simple_epoll_server_test.cc b/epoll_server/simple_epoll_server_test.cc
new file mode 100644
index 0000000..140eb2b
--- /dev/null
+++ b/epoll_server/simple_epoll_server_test.cc
@@ -0,0 +1,2517 @@
+// 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 <hash_map>
+#include <memory>
+#include <string>
+#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_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);
+  }
+
+  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) {
+      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(2, records->size());
+
+  // Call handle event and make sure something was recorded.
+  ep()->HandleEvent(fd(), EPOLLOUT);
+  ep()->CallReadyListCallbacks();
+  EXPECT_EQ(3, records->size());
+
+  // Call handle event and make sure something was recorded.
+  ep()->HandleEvent(fd(), EPOLLIN | O_NONBLOCK);
+  ep()->CallReadyListCallbacks();
+  EXPECT_EQ(4, 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) {
+  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 __gnu_cxx::hash_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(1, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, 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(1, 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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+  int64_t first_now = ep.ApproximateNowInUsec();
+  EXPECT_LT(0, 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(1, 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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, 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(2, 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(1, 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(2, 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(0, 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(1, 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(0, 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(1, 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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  EXPECT_TRUE(alarm2.onunregistration_called());
+
+  if (alarm1.get_token(&temptok)) {
+    ep.UnregisterAlarm(temptok);
+  }
+  EXPECT_EQ(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  ASSERT_TRUE(alarm.get_token(&token));
+  ep.ReregisterAlarm(token, 6000);
+  EXPECT_EQ(1, 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(1, 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(2, 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(2, 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(2, 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(3, 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(4, 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(2, 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(2, records_one->size());
+  EXPECT_EQ(2, records_two->size());
+
+  write(pipe_one[1], &data, 1);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3, records_one->size());
+  EXPECT_EQ(2, records_two->size());
+
+
+  write(pipe_two[1], &data, 1);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3, records_one->size());
+  EXPECT_EQ(3, records_two->size());
+
+  write(pipe_one[1], &data, 1);
+  write(pipe_two[1], &data, 1);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(4, records_one->size());
+  EXPECT_EQ(4, 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 {}
+
+  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(2, 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(3, records->size());
+  EXPECT_FALSE(alarm.was_called());
+  ep.RegisterAlarm(WallTimeNowInUsec() + 1000, &alarm);
+  WaitForAlarm(&ep, alarm);
+  EXPECT_EQ(3, 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(4, 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);
+  }
+
+  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) {
+    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) {
+        PLOG(FATAL) << "write() failed";
+      }
+      close(writer_pipe);
+
+      _exit(0);
+    }
+    case -1:
+      PLOG(FATAL) << "fork() failed";
+      break;
+    default: {  // Parent will receive message.
+      close(writer_pipe);
+      auto ep = absl::make_unique<SimpleEpollServer>();
+      ep->set_timeout_in_us(1);
+      EpollReader reader(len);
+      ep->RegisterFD(reader_pipe, &reader, EPOLLIN);
+
+      int64_t start_ms = WallTimeNowInUsec() / 1000;
+      // Loop until we're either done reading, or have waited ~10 us.
+      while (!reader.done_reading() &&
+             (WallTimeNowInUsec() / 1000 - start_ms) < 10000) {
+        ep->WaitForEventsAndExecuteCallbacks();
+      }
+      ep->UnregisterFD(reader_pipe);
+      CHECK(reader.CheckOutput(test_message, len));
+      break;
+    }
+  }
+
+  close(reader_pipe);
+  close(writer_pipe);
+}
+
+TEST(SimpleEpollServerTest, TestSmallPipe) {
+  char buf[kMaxBufLen];
+  TestPipe(buf, 10);
+}
+
+TEST(SimpleEpollServerTest, TestLargePipe) {
+  char buf[kMaxBufLen];
+  TestPipe(buf, kMaxBufLen);
+}
+
+// Tests RegisterFDForRead as well as StopRead.
+TEST(SimpleEpollServerTest, TestRead) {
+  SimpleEpollServer ep;
+  ep.set_timeout_in_us(1);
+  int len = 1;
+
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int read_fd = pipe_fds[0];
+  int write_fd = pipe_fds[1];
+
+  auto reader = absl::make_unique<EpollReader>(len);
+
+  // Check that registering a FD for read alerts us when there is data to be
+  // read.
+  ep.RegisterFDForRead(read_fd, reader.get());
+  char data = 'a';
+  int size = write(write_fd, &data, 1);
+  EXPECT_EQ(1, size);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(reader->CheckOutput(&data, len));
+
+  // Remove the callback for read events, write to the pipe and make sure that
+  // we did not read more data.
+  ep.StopRead(read_fd);
+  size = write(write_fd, &data, len);
+  EXPECT_EQ(1, size);
+  // The wait will return after timeout.
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(reader->CheckOutput(&data, len));
+  ep.UnregisterFD(read_fd);
+
+  close(read_fd);
+  close(write_fd);
+}
+
+class EdgeTriggerCB : public EpollCallbackInterface {
+ public:
+  EdgeTriggerCB(int read_size, int write_size, char write_char, char peer_char)
+      : eps_(nullptr),
+        read_buf_(read_size),
+        write_buf_(write_size, write_char),
+        peer_char_(peer_char) {
+    Reset();
+  }
+
+  ~EdgeTriggerCB() override {}
+
+  void Reset() {
+    CHECK(eps_ == nullptr);
+    bytes_read_ = 0;
+    bytes_written_ = 0;
+    can_read_ = false;
+    will_read_ = false;
+    can_write_ = false;
+    will_write_ = false;
+    read_closed_ = false;
+    write_closed_ = false;
+  }
+
+  void ResetByteCounts() {
+    bytes_read_ = bytes_written_ = 0;
+  }
+
+  void set_will_read(bool will_read) { will_read_ = will_read; }
+
+  void set_will_write(bool will_write) { will_write_ = will_write; }
+
+  bool can_write() const { return can_write_; }
+
+  int bytes_read() const { return bytes_read_; }
+
+  int bytes_written() const { return bytes_written_; }
+
+  void OnRegistration(SimpleEpollServer* eps, int fd, int event_mask) override {
+    EXPECT_TRUE(eps_ == nullptr);
+    eps_ = eps;
+    Initialize(fd, event_mask);
+  }
+
+  void OnModification(int fd, int event_mask) override {
+    EXPECT_TRUE(eps_ != nullptr);
+    if (event_mask & EPOLLET) {
+      Initialize(fd, event_mask);
+    } else {
+      eps_->SetFDNotReady(fd);
+    }
+  }
+
+  void OnEvent(int fd, EpollEvent* event) override {
+    const int event_mask = event->in_events;
+    if (event_mask & (EPOLLHUP | EPOLLERR)) {
+      write_closed_ = true;
+      return;
+    }
+    if (will_read_ && event_mask & EPOLLIN) {
+      EXPECT_FALSE(read_closed_);
+      int read_size = read_buf_.size();
+      memset(&read_buf_[0], 0, read_size);
+      int len = recv(fd, &read_buf_[0], read_size, MSG_DONTWAIT);
+      // Update the readiness states
+      can_read_ = (len == read_size);
+
+      if (len > 0) {
+        bytes_read_ += len;
+        EPOLL_VLOG(1) << "fd: " << fd << ", read " << len
+                      << ", total: " << bytes_read_;
+        // Now check the bytes read
+        EXPECT_TRUE(CheckReadBuffer(len));
+      } else if (len < 0) {
+        EPOLL_VLOG(1) << "fd: " << fd << " read hit EAGAIN";
+        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
+        can_read_ = false;
+      } else {
+        read_closed_ = true;
+      }
+    }
+    if (will_write_ && event_mask & EPOLLOUT) {
+      // Write side close/full close can only detected by EPOLLHUP, which is
+      // caused by EPIPE.
+      EXPECT_FALSE(write_closed_);
+      int write_size = write_buf_.size();
+      int len = send(fd, &write_buf_[0], write_size, MSG_DONTWAIT);
+      can_write_ = (len == write_size);
+      if (len > 0) {
+        bytes_written_ += len;
+        EPOLL_VLOG(1) << "fd: " << fd << ", write " << len
+                      << ", total: " << bytes_written_;
+      } else {
+        EPOLL_VLOG(1) << "fd: " << fd << " write hit EAGAIN";
+        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
+        can_write_ = false;
+      }
+    }
+    // Since we can only get on the ready list once, wait till we confirm both
+    // read and write side continuation state and set the correct event mask
+    // for the ready list.
+    event->out_ready_mask = can_read_ ? 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);
+  }
+
+  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(1, ep.ReadyListSize());
+  ep.SetFDReady(pipe_fds[1], EPOLLOUT);
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
+  EXPECT_EQ(2, 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(1, ep.ReadyListSize());
+
+  ep.UnregisterFD(pipe_fds[0]);
+  ep.UnregisterFD(pipe_fds[1]);
+  EXPECT_EQ(0, 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(0, 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 {}
+  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 {}
+  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 {}
+  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 {}
+  string Name() const override { return "UnRegEverythingReadyListOnEvent"; }
+
+ protected:
+  SimpleEpollServer* eps_;
+  int fd_;
+  int fd_range_;
+  int* num_called_;
+};
+
+TEST(SimpleEpollServerTest,
+     NothingBadWhenUnRegisteredWhileProcessingFromReadyList) {
+  UnRegEverythingReadyListOnEvent callbacks[32];
+  int num_called = 0;
+  {
+    FakeSimpleEpollServer epoll_server;
+    for (size_t i = 0; i < ABSL_ARRAYSIZE(callbacks); ++i) {
+      callbacks[i].set_fd(-i);
+      callbacks[i].set_fd_range(ABSL_ARRAYSIZE(callbacks));
+      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 {}
+  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 {}
+
+  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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  alarm.ReregisterAlarm(6000);
+  EXPECT_EQ(1, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(5000);
+  ep.set_timeout_in_us(0);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_EQ(1, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(6000);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_EQ(0, 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