proxygen
EventHandlerTest.cpp File Reference
#include <bitset>
#include <future>
#include <thread>
#include <folly/MPMCQueue.h>
#include <folly/ScopeGuard.h>
#include <folly/io/async/EventBase.h>
#include <folly/io/async/EventHandler.h>
#include <folly/portability/GMock.h>
#include <folly/portability/GTest.h>
#include <folly/portability/Sockets.h>
#include <sys/eventfd.h>

Go to the source code of this file.

Classes

class  EventHandlerMock
 
class  EventHandlerTest
 

Functions

void runInThreadsAndWait (size_t nthreads, function< void(size_t)> cb)
 
void runInThreadsAndWait (vector< function< void()>> cbs)
 
 TEST_F (EventHandlerTest, simple)
 
 TEST_F (EventHandlerTest, many_concurrent_producers)
 
 TEST_F (EventHandlerTest, many_concurrent_consumers)
 

Function Documentation

void runInThreadsAndWait ( size_t  nthreads,
function< void(size_t)>  cb 
)

Definition at line 34 of file EventHandlerTest.cpp.

References i, nthreads, and threads.

Referenced by runInThreadsAndWait(), and TEST_F().

34  {
35  vector<thread> threads(nthreads);
36  for (size_t i = 0; i < nthreads; ++i) {
37  threads[i] = thread(cb, i);
38  }
39  for (size_t i = 0; i < nthreads; ++i) {
40  threads[i].join();
41  }
42 }
std::vector< std::thread::id > threads
static int nthreads
void runInThreadsAndWait ( vector< function< void()>>  cbs)

Definition at line 44 of file EventHandlerTest.cpp.

References k, and runInThreadsAndWait().

44  {
45  runInThreadsAndWait(cbs.size(), [&](size_t k) { cbs[k](); });
46 }
void runInThreadsAndWait(size_t nthreads, function< void(size_t)> cb)
KeyT k
TEST_F ( EventHandlerTest  ,
simple   
)

Definition at line 85 of file EventHandlerTest.cpp.

References testing::_, EXPECT_CALL, EXPECT_EQ, testing::Invoke(), folly::EventBase::loop(), folly::EventHandler::registerHandler(), uint16_t, and folly::EventHandler::unregisterHandler().

Referenced by TEST_F().

85  {
86  const size_t writes = 4;
87  size_t readsRemaining = writes;
88 
89  EventBase eb;
90  EventHandlerMock eh(&eb, efd);
91  eh.registerHandler(EventHandler::READ | EventHandler::PERSIST);
92  EXPECT_CALL(eh, _handlerReady(_))
93  .Times(writes)
94  .WillRepeatedly(Invoke([&](uint16_t /* events */) {
95  efd_read();
96  if (--readsRemaining == 0) {
97  eh.unregisterHandler();
98  }
99  }));
100  efd_write(writes);
101  eb.loop();
102 
103  EXPECT_EQ(0, readsRemaining);
104 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
TEST_F ( EventHandlerTest  ,
many_concurrent_producers   
)

Definition at line 106 of file EventHandlerTest.cpp.

References testing::_, EXPECT_CALL, EXPECT_EQ, i, testing::Invoke(), folly::EventBase::loop(), folly::EventHandler::registerHandler(), runInThreadsAndWait(), uint16_t, and folly::EventHandler::unregisterHandler().

106  {
107  const size_t writes = 200;
108  const size_t nproducers = 20;
109  size_t readsRemaining = writes;
110 
112  [&] {
113  EventBase eb;
114  EventHandlerMock eh(&eb, efd);
115  eh.registerHandler(EventHandler::READ | EventHandler::PERSIST);
116  EXPECT_CALL(eh, _handlerReady(_))
117  .Times(writes)
118  .WillRepeatedly(Invoke([&](uint16_t /* events */) {
119  efd_read();
120  if (--readsRemaining == 0) {
121  eh.unregisterHandler();
122  }
123  }));
124  eb.loop();
125  },
126  [&] {
127  runInThreadsAndWait(nproducers, [&](size_t /* k */) {
128  for (size_t i = 0; i < writes / nproducers; ++i) {
129  this_thread::sleep_for(std::chrono::milliseconds(1));
130  efd_write(1);
131  }
132  });
133  },
134  });
135 
136  EXPECT_EQ(0, readsRemaining);
137 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void runInThreadsAndWait(size_t nthreads, function< void(size_t)> cb)
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
TEST_F ( EventHandlerTest  ,
many_concurrent_consumers   
)

Definition at line 139 of file EventHandlerTest.cpp.

References testing::_, folly::netops::accept(), ASSERT_TRUE, folly::netops::bind(), buffer(), folly::netops::close(), folly::netops::connect(), EXPECT_CALL, EXPECT_EQ, EXPECT_TRUE, folly::netops::getsockname(), i, folly::INFO, testing::Invoke(), folly::netops::listen(), folly::EventBase::loop(), folly::pushmi::__adl::noexcept(), fizz::detail::read(), folly::netops::recv(), folly::EventHandler::registerHandler(), runInThreadsAndWait(), SCOPE_EXIT, folly::netops::send(), folly::netops::socket(), string, TEST_F(), uint16_t, folly::EventHandler::unregisterHandler(), and val.

139  {
140  const size_t writes = 200;
141  const size_t nproducers = 8;
142  const size_t nconsumers = 20;
143  atomic<size_t> writesRemaining(writes);
144  atomic<size_t> readsRemaining(writes);
145 
146  MPMCQueue<nullptr_t> queue(writes / 10);
147 
149  [&] {
150  runInThreadsAndWait(nconsumers, [&](size_t /* k */) {
151  size_t thReadsRemaining = writes / nconsumers;
152  EventBase eb;
153  EventHandlerMock eh(&eb, efd);
154  eh.registerHandler(EventHandler::READ | EventHandler::PERSIST);
155  EXPECT_CALL(eh, _handlerReady(_))
156  .WillRepeatedly(Invoke([&](uint16_t /* events */) {
157  nullptr_t val;
158  if (!queue.readIfNotEmpty(val)) {
159  return;
160  }
161  efd_read();
162  --readsRemaining;
163  if (--thReadsRemaining == 0) {
164  eh.unregisterHandler();
165  }
166  }));
167  eb.loop();
168  });
169  },
170  [&] {
171  runInThreadsAndWait(nproducers, [&](size_t /* k */) {
172  for (size_t i = 0; i < writes / nproducers; ++i) {
173  this_thread::sleep_for(std::chrono::milliseconds(1));
174  queue.blockingWrite(nullptr);
175  efd_write(1);
176  --writesRemaining;
177  }
178  });
179  },
180  });
181 
182  EXPECT_EQ(0, writesRemaining);
183  EXPECT_EQ(0, readsRemaining);
184 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
double val
Definition: String.cpp:273
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void runInThreadsAndWait(size_t nthreads, function< void(size_t)> cb)
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _