proxygen
RateLimiterTest.cpp File Reference
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
#include <folly/Conv.h>
#include <folly/logging/RateLimiter.h>
#include <folly/portability/GTest.h>

Go to the source code of this file.

Typedefs

using irl_clock = IntervalRateLimiter::clock
 

Functions

void intervalTest (uint64_t eventsPerInterval, irl_clock::duration interval)
 
 TEST (RateLimiter, interval3per100ms)
 
 TEST (RateLimiter, interval1per100ms)
 
 TEST (RateLimiter, interval15per150ms)
 
 TEST (RateLimiter, concurrentThreads)
 

Typedef Documentation

using irl_clock = IntervalRateLimiter::clock

Definition at line 31 of file RateLimiterTest.cpp.

Function Documentation

void intervalTest ( uint64_t  eventsPerInterval,
irl_clock::duration  interval 
)

Definition at line 33 of file RateLimiterTest.cpp.

References count, EXPECT_FALSE, EXPECT_TRUE, now(), SCOPED_TRACE, and uint64_t.

Referenced by TEST().

33  {
34  SCOPED_TRACE(folly::to<std::string>(
35  eventsPerInterval,
36  " events every ",
37  duration_cast<std::chrono::milliseconds>(interval).count(),
38  "ms"));
39  IntervalRateLimiter limiter{eventsPerInterval, interval};
40  for (int iter = 0; iter < 4; ++iter) {
41  if (iter != 0) {
42  auto now = irl_clock::now();
43  auto const deadline = now + interval;
44  while (now < deadline) {
45  /* sleep override */
46  std::this_thread::sleep_for(now - deadline);
47  now = irl_clock::now();
48  }
49  }
50  for (uint64_t n = 0; n < eventsPerInterval * 2; ++n) {
51  if (n < eventsPerInterval) {
52  EXPECT_TRUE(limiter.check())
53  << "expected check success on loop " << iter << " event " << n;
54  } else {
55  EXPECT_FALSE(limiter.check())
56  << "expected check failure on loop " << iter << " event " << n;
57  }
58  }
59  }
60 }
std::chrono::steady_clock::time_point now()
#define SCOPED_TRACE(message)
Definition: gtest.h:2115
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( RateLimiter  ,
interval3per100ms   
)

Definition at line 62 of file RateLimiterTest.cpp.

References intervalTest().

62  {
63  intervalTest(3, 100ms);
64 }
void intervalTest(uint64_t eventsPerInterval, irl_clock::duration interval)
TEST ( RateLimiter  ,
interval1per100ms   
)

Definition at line 66 of file RateLimiterTest.cpp.

References intervalTest().

66  {
67  intervalTest(1, 100ms);
68 }
void intervalTest(uint64_t eventsPerInterval, irl_clock::duration interval)
TEST ( RateLimiter  ,
interval15per150ms   
)

Definition at line 70 of file RateLimiterTest.cpp.

References intervalTest().

70  {
71  intervalTest(15, 150ms);
72 }
void intervalTest(uint64_t eventsPerInterval, irl_clock::duration interval)
TEST ( RateLimiter  ,
concurrentThreads   
)

Definition at line 74 of file RateLimiterTest.cpp.

References count, EXPECT_EQ, folly::detail::lock(), m, mutex, s, threads, and uint64_t.

74  {
75  constexpr uint64_t maxEvents = 20;
76  constexpr uint64_t numThreads = 32;
77 
78  IntervalRateLimiter limiter{20, 10s};
79  std::atomic<uint32_t> count{0};
80  std::mutex m;
81  std::condition_variable cv;
82  bool go = false;
83 
84  auto threadMain = [&]() {
85  // Have each thread wait for go to become true before starting.
86  // This hopefully gives us the best chance of having all threads start
87  // at close to the same time.
88  {
89  std::unique_lock<std::mutex> lock{m};
90  cv.wait(lock, [&go] { return go; });
91  }
92 
93  for (uint64_t iteration = 0; iteration < maxEvents * 2; ++iteration) {
94  if (limiter.check()) {
95  count.fetch_add(1, std::memory_order_relaxed);
96  }
97  }
98  };
99 
100  // Start the threads
101  std::vector<std::thread> threads;
102  threads.reserve(numThreads);
103  for (uint64_t n = 0; n < numThreads; ++n) {
104  threads.emplace_back(threadMain);
105  }
106 
107  // Set go to true and notify all the threads
108  {
109  std::lock_guard<std::mutex> lg(m);
110  go = true;
111  }
112  cv.notify_all();
113 
114  // Wait for all of the threads
115  for (auto& thread : threads) {
116  thread.join();
117  }
118 
119  // We should have passed the check exactly maxEvents times
120  EXPECT_EQ(maxEvents, count.load(std::memory_order_relaxed));
121 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::vector< std::thread::id > threads
auto lock(SynchronizedLocker...lockersIn) -> std::tuple< typename SynchronizedLocker::LockedPtr... >
Definition: Synchronized.h:871
static map< string, int > m
int * count
std::mutex mutex
static set< string > s