proxygen
SlidingBloomReplayCacheTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
13 
14 #include <folly/Random.h>
15 
16 #include <unordered_set>
17 
18 using namespace folly;
19 
20 namespace fizz {
21 namespace server {
22 namespace test {
23 
24 static std::string generateRandomString(size_t minimum, size_t maximum) {
25  size_t length = Random::rand64(minimum, maximum + 1);
26  auto randchar = []() -> char {
27  const char kCharset[] =
28  "0123456789+/=-_"
29  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
30  "abcdefghijklmnopqrstuvwxyz";
31  return kCharset[Random::rand64(0, sizeof(kCharset))];
32  };
33  std::string str(length, 0);
34  std::generate_n(str.begin(), length, randchar);
35  return str;
36 }
37 
38 static folly::ByteRange toRange(const std::string& str) {
40 }
41 
42 TEST(SlidingBloomReplayCacheTest, TestSimpleGetSet) {
43  const int numTries = 1 << 14;
44  SlidingBloomReplayCache cache(12, numTries, 0.0005, nullptr);
45  std::vector<std::string> history(numTries);
46  for (size_t i = 0; i < numTries; i++) {
47  history[i] = generateRandomString(8, 64);
48  EXPECT_FALSE(cache.test(toRange(history[i])));
49  }
50  for (size_t i = 0; i < numTries; i++) {
51  cache.set(toRange(history[i]));
52  EXPECT_TRUE(cache.test(toRange(history[i])));
53  }
54 }
55 
56 TEST(SlidingBloomReplayCacheTest, TestSimpleTestAndSet) {
57  const int numTries = 1 << 14;
58  SlidingBloomReplayCache cache(12, numTries, 0.0005, nullptr);
59  std::vector<std::string> history(numTries);
60  size_t falsePositives = 0;
61  for (size_t i = 0; i < numTries; i++) {
62  history[i] = generateRandomString(8, 64);
63  if (cache.testAndSet(toRange(history[i]))) {
64  falsePositives++;
65  }
66  }
67 
68  for (size_t i = 0; i < numTries; i++) {
69  EXPECT_TRUE(cache.test(toRange(history[i])));
70  }
71 
72  double actualErrorRate = static_cast<double>(falsePositives) / numTries;
73  EXPECT_LT(actualErrorRate, 0.0005);
74 }
75 
76 TEST(SlidingBloomReplayCacheTest, TestCacheErrorRate) {
77  const int numTries = 1 << 14;
78  SlidingBloomReplayCache cache(12, numTries, 0.0005, nullptr);
79  std::vector<std::string> history(numTries);
80  for (size_t i = 0; i < numTries; i++) {
81  history[i] = generateRandomString(8, 64);
82  cache.set(toRange(history[i]));
83  }
84 
85  size_t falsePositives = 0;
86  std::unordered_set<std::string> seen(history.begin(), history.end());
87 
88  for (size_t i = 0; i < numTries; i++) {
90  do {
91  needle = generateRandomString(8, 64);
92  } while (seen.count(needle) == 1);
93  seen.insert(needle);
94  if (cache.test(toRange(needle))) {
95  falsePositives++;
96  }
97  }
98 
99  double actualErrorRate = static_cast<double>(falsePositives) / numTries;
100  EXPECT_LT(actualErrorRate, 0.001);
101 }
102 
103 TEST(SlidingBloomReplayCacheTest, TestTimeBucketing) {
104  const int numTries = 1 << 14;
105 
106  folly::EventBase evb;
107  SlidingBloomReplayCache cache(12, numTries, 0.0005, &evb);
108 
109  std::vector<std::string> history(numTries);
110  for (size_t i = 0; i < numTries; i++) {
111  history[i] = generateRandomString(8, 64);
112  cache.set(toRange(history[i]));
113  }
114 
115  // 6 seconds in, all values should still be set
116  evb.scheduleAt(
117  [&] {
118  for (int i = 0; i < numTries; ++i) {
119  EXPECT_TRUE(cache.test(toRange(history[i])));
120  }
121  },
122  evb.now() + std::chrono::seconds(6));
123 
124  // 13 seconds in, all should be gone.
125  evb.scheduleAt(
126  [&] {
127  for (int i = 0; i < numTries; ++i) {
128  EXPECT_FALSE(cache.test(toRange(history[i])));
129  }
130  evb.terminateLoopSoon();
131  },
132  evb.now() + std::chrono::seconds(13));
133  evb.loop();
134 }
135 } // namespace test
136 } // namespace server
137 } // namespace fizz
const string needle
static std::string generateRandomString(size_t minimum, size_t maximum)
bool test(folly::ByteRange query) const
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void scheduleAt(Func &&fn, TimePoint const &timeout) override
Definition: EventBase.cpp:754
std::unordered_set< std::pair< const IValidator *, const dynamic * > > seen
Definition: JSONSchema.cpp:92
virtual TimePoint now()
Get this executor&#39;s notion of time. Must be threadsafe.
void terminateLoopSoon()
Definition: EventBase.cpp:493
Definition: Actions.h:16
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
const char * string
Definition: Conv.cpp:212
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
#define EXPECT_LT(val1, val2)
Definition: gtest.h:1930
static uint64_t rand64()
Definition: Random.h:263
TEST(SequencedExecutor, CPUThreadPoolExecutor)
static folly::ByteRange toRange(const std::string &str)