proxygen
FilePersistentCacheTest.cpp File Reference

Go to the source code of this file.

Classes

class  FilePersistentCacheTest< MutexT >
 

Typedefs

using MutexTypes = ::testing::Types< std::mutex, folly::SharedMutex >
 

Functions

 TYPED_TEST_CASE (FilePersistentCacheTest, MutexTypes)
 
 TYPED_TEST (FilePersistentCacheTest, stringTypesGetPutTest)
 
 TYPED_TEST (FilePersistentCacheTest, basicTypeGetPutTest)
 
 TYPED_TEST (FilePersistentCacheTest, stringCompositeGetPutTest)
 
 TYPED_TEST (FilePersistentCacheTest, stringNestedValGetPutTest)
 
 TYPED_TEST (FilePersistentCacheTest, stringNestedKeyValGetPutTest)
 
template<typename K , typename V , typename MutexT >
void testEmptyFile ()
 
 TYPED_TEST (FilePersistentCacheTest, stringTypesEmptyFile)
 
 TYPED_TEST (FilePersistentCacheTest, stringNestedValEmptyFile)
 
template<typename K , typename V , typename MutexT >
void testInvalidFile (const std::string &content)
 
 TYPED_TEST (FilePersistentCacheTest, stringTypesInvalidFile)
 
 TYPED_TEST (FilePersistentCacheTest, stringNestedValInvalidFile)
 
template<typename K , typename V , typename MutexT >
void testValidFile (const std::string &content, const vector< K > &keys, const vector< V > &values)
 
 TYPED_TEST (FilePersistentCacheTest, stringTypesValidFileTest)
 
 TYPED_TEST (FilePersistentCacheTest, basicEvictionTest)
 
 TYPED_TEST (FilePersistentCacheTest, backwardCompatiblityTest)
 
 TYPED_TEST (FilePersistentCacheTest, destroy)
 
 TYPED_TEST (FilePersistentCacheTest, threadstress)
 

Typedef Documentation

using MutexTypes = ::testing::Types<std::mutex, folly::SharedMutex>

Definition at line 30 of file FilePersistentCacheTest.cpp.

Function Documentation

template<typename K , typename V , typename MutexT >
void testEmptyFile ( )

Definition at line 96 of file FilePersistentCacheTest.cpp.

References folly::closeNoInt(), EXPECT_EQ, EXPECT_TRUE, wangle::getPersistentCacheFilename(), and folly::openNoInt().

96  {
97  string filename = getPersistentCacheFilename();
98  size_t cacheCapacity = 10;
99  int fd = folly::openNoInt(
100  filename.c_str(),
101  O_WRONLY | O_CREAT | O_TRUNC,
102  S_IRUSR | S_IWUSR
103  );
104  EXPECT_TRUE(fd != -1);
105  using CacheType = FilePersistentCache<K, V, MutexT>;
106  CacheType cache(filename, cacheCapacity, chrono::seconds(1));
107  EXPECT_EQ(cache.size(), 0);
108  EXPECT_TRUE(folly::closeNoInt(fd) != -1);
109  EXPECT_TRUE(unlink(filename.c_str()) != -1);
110 }
int closeNoInt(int fd)
Definition: FileUtil.cpp:56
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
int openNoInt(const char *name, int flags, mode_t mode)
Definition: FileUtil.cpp:36
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
template<typename K , typename V , typename MutexT >
void testInvalidFile ( const std::string content)

Definition at line 126 of file FilePersistentCacheTest.cpp.

References folly::closeNoInt(), EXPECT_EQ, EXPECT_TRUE, wangle::getPersistentCacheFilename(), folly::openNoInt(), and folly::writeFull().

126  {
127  string filename = getPersistentCacheFilename();
128  size_t cacheCapacity = 10;
129  int fd = folly::openNoInt(
130  filename.c_str(),
131  O_WRONLY | O_CREAT | O_TRUNC,
132  S_IRUSR | S_IWUSR
133  );
134  EXPECT_TRUE(fd != -1);
135  EXPECT_EQ(
136  folly::writeFull(fd, content.data(), content.size()),
137  content.size()
138  );
139  using CacheType = FilePersistentCache<K, V, MutexT>;
140  CacheType cache(filename, cacheCapacity, chrono::seconds(1));
141  EXPECT_EQ(cache.size(), 0);
142  EXPECT_TRUE(folly::closeNoInt(fd) != -1);
143  EXPECT_TRUE(unlink(filename.c_str()) != -1);
144 }
int closeNoInt(int fd)
Definition: FileUtil.cpp:56
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
ssize_t writeFull(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:134
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
int openNoInt(const char *name, int flags, mode_t mode)
Definition: FileUtil.cpp:36
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
template<typename K , typename V , typename MutexT >
void testValidFile ( const std::string content,
const vector< K > &  keys,
const vector< V > &  values 
)

Definition at line 160 of file FilePersistentCacheTest.cpp.

References folly::closeNoInt(), EXPECT_EQ, EXPECT_TRUE, wangle::getPersistentCacheFilename(), i, folly::openNoInt(), and folly::writeFull().

164  {
165  string filename = getPersistentCacheFilename();
166  size_t cacheCapacity = 10;
167  int fd = folly::openNoInt(
168  filename.c_str(),
169  O_WRONLY | O_CREAT | O_TRUNC,
170  S_IRUSR | S_IWUSR
171  );
172  EXPECT_TRUE(fd != -1);
173  EXPECT_EQ(
174  folly::writeFull(fd, content.data(), content.size()),
175  content.size()
176  );
177  using CacheType = FilePersistentCache<K, V, MutexT>;
178  CacheType cache(filename, cacheCapacity, chrono::seconds(1));
179  EXPECT_EQ(cache.size(), keys.size());
180  for (size_t i = 0; i < keys.size(); ++i) {
181  EXPECT_EQ(cache.get(keys[i]).value(), values[i]);
182  }
183  EXPECT_TRUE(folly::closeNoInt(fd) != -1);
184  EXPECT_TRUE(unlink(filename.c_str()) != -1);
185 }
int closeNoInt(int fd)
Definition: FileUtil.cpp:56
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
ssize_t writeFull(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:134
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
int openNoInt(const char *name, int flags, mode_t mode)
Definition: FileUtil.cpp:36
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
TYPED_TEST ( FilePersistentCacheTest  ,
stringTypesGetPutTest   
)

Definition at line 33 of file FilePersistentCacheTest.cpp.

References string, and values().

33  {
34  using KeyType = string;
35  using ValType = string;
36  vector<KeyType> keys = {"key1", "key2"};
37  vector<ValType> values = {"value1", "value2"};
38  testSimplePutGet<KeyType, ValType, TypeParam>(keys, values);
39 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
basicTypeGetPutTest   
)

Definition at line 41 of file FilePersistentCacheTest.cpp.

References values().

41  {
42  using KeyType = int;
43  using ValType = double;
44  vector<KeyType> keys = {1, 2};
45  vector<ValType> values = {3.0, 4.0};
46  testSimplePutGet<KeyType, ValType, TypeParam>(keys, values);
47 }
KeyType
Definition: Signature.h:17
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
stringCompositeGetPutTest   
)

Definition at line 49 of file FilePersistentCacheTest.cpp.

References string, and values().

49  {
50  using KeyType = string;
51  using ValType = list<string>;
52  vector<KeyType> keys = {"key1", "key2"};
53  vector<ValType> values =
54  {ValType({"fma", "shijin"}), ValType({"foo", "bar"})};
55  testSimplePutGet<KeyType, ValType, TypeParam>(keys, values);
56 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
stringNestedValGetPutTest   
)

Definition at line 58 of file FilePersistentCacheTest.cpp.

References string, and values().

58  {
59  using KeyType = string;
60  using ValType = map<string, list<string>>;
61  vector<KeyType> keys = {"cool", "not cool"};
62  vector<ValType> values = {
63  ValType({
64  {"NYC", {"fma", "shijin"}},
65  {"MPK", {"ranjeeth", "dsp"}}
66  }),
67  ValType({
68  {"MPK", {"subodh", "blake"}},
69  {"STL", {"pgriess"}}
70  }),
71  };
72  testSimplePutGet<KeyType, ValType, TypeParam>(keys, values);
73 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
stringNestedKeyValGetPutTest   
)

Definition at line 75 of file FilePersistentCacheTest.cpp.

References values().

75  {
76  using KeyType = pair<string, string>;
77  using ValType = map<string, list<string>>;
78  vector<KeyType> keys = {
79  make_pair("cool", "what the=?"),
80  make_pair("not_cool", "how on *& earth?")
81  };
82  vector<ValType> values = {
83  ValType({
84  {"NYC", {"fma", "shijin kong$"}},
85  {"MPK", {"ranjeeth", "dsp"}}
86  }),
87  ValType({
88  {"MPK", {"subodh", "blake"}},
89  {"STL", {"pgriess"}}
90  }),
91  };
92  testSimplePutGet<KeyType, ValType, TypeParam>(keys, values);
93 }
KeyType
Definition: Signature.h:17
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
stringTypesEmptyFile   
)

Definition at line 112 of file FilePersistentCacheTest.cpp.

References string.

112  {
113  using KeyType = string;
114  using ValType = string;
115  testEmptyFile<KeyType, ValType, TypeParam>();
116 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
TYPED_TEST ( FilePersistentCacheTest  ,
stringNestedValEmptyFile   
)

Definition at line 118 of file FilePersistentCacheTest.cpp.

References string.

118  {
119  using KeyType = string;
120  using ValType = map<string, list<string>>;
121  testEmptyFile<KeyType, ValType, TypeParam>();
122 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
TYPED_TEST ( FilePersistentCacheTest  ,
stringTypesInvalidFile   
)

Definition at line 146 of file FilePersistentCacheTest.cpp.

References string.

146  {
147  using KeyType = string;
148  using ValType = string;
149  testInvalidFile<KeyType, ValType, TypeParam>(string("{\"k1\":\"v1\",1}"));
150 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
TYPED_TEST ( FilePersistentCacheTest  ,
stringNestedValInvalidFile   
)

Definition at line 152 of file FilePersistentCacheTest.cpp.

References string.

152  {
153  using KeyType = string;
154  using ValType = map<string, list<string>>;
155  testInvalidFile<KeyType, ValType, TypeParam>(string("{\"k1\":\"v1\"}"));
156 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
TYPED_TEST ( FilePersistentCacheTest  ,
stringTypesValidFileTest   
)

Definition at line 187 of file FilePersistentCacheTest.cpp.

References string, and values().

187  {
188  using KeyType = string;
189  using ValType = string;
190  vector<KeyType> keys = {"key1", "key2"};
191  vector<ValType> values = {"value1", "value2"};
192  std::string content = "[[\"key1\",\"value1\"], [\"key2\",\"value2\"]]";
193  testValidFile<KeyType, ValType, TypeParam>(content, keys, values);
194 }
KeyType
Definition: Signature.h:17
const char * string
Definition: Conv.cpp:212
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
basicEvictionTest   
)

Definition at line 196 of file FilePersistentCacheTest.cpp.

References EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, wangle::FilePersistentCache< K, V, M >::get(), wangle::getPersistentCacheFilename(), folly::Optional< Value >::hasValue(), i, wangle::FilePersistentCache< K, V, M >::put(), wangle::FilePersistentCache< K, V, M >::size(), and folly::Optional< Value >::value().

196  {
197  string filename = getPersistentCacheFilename();
198  {
199  size_t cacheCapacity = 10;
201  cacheCapacity, chrono::seconds(1));
202  for (int i = 0; i < 10; ++i) {
203  cache.put(i, i);
204  }
205  EXPECT_EQ(cache.size(), 10); // MRU to LRU : 9, 8, ...1, 0
206 
207  cache.put(10, 10); // evicts 0
208  EXPECT_EQ(cache.size(), 10);
209  EXPECT_FALSE(cache.get(0).hasValue());
210  EXPECT_EQ(cache.get(10).value(), 10); // MRU to LRU : 10, 9, ... 2, 1
211 
212  EXPECT_EQ(cache.get(1).value(), 1); // MRU to LRU : 1, 10, 9, ..., 3, 2
213  cache.put(11, 11); // evicts 2
214  EXPECT_EQ(cache.size(), 10);
215  EXPECT_FALSE(cache.get(2).hasValue());
216  EXPECT_EQ(cache.get(11).value(), 11);
217  }
218 
219  EXPECT_TRUE(unlink(filename.c_str()) != -1);
220 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
TYPED_TEST ( FilePersistentCacheTest  ,
backwardCompatiblityTest   
)

Definition at line 223 of file FilePersistentCacheTest.cpp.

References folly::closeNoInt(), EXPECT_EQ, EXPECT_TRUE, wangle::getPersistentCacheFilename(), folly::openNoInt(), string, values(), and folly::writeFull().

223  {
224  using KeyType = string;
225  using ValType = string;
226 
227  // write an old style file
228  vector<KeyType> keys = {"key1", "key2"};
229  vector<ValType> values = {"value1", "value2"};
230  std::string content = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
232  string filename = getPersistentCacheFilename();
233  size_t cacheCapacity = 10;
234  int fd = folly::openNoInt(
235  filename.c_str(),
236  O_WRONLY | O_CREAT | O_TRUNC,
237  S_IRUSR | S_IWUSR
238  );
239  EXPECT_TRUE(fd != -1);
240  EXPECT_EQ(
241  folly::writeFull(fd, content.data(), content.size()),
242  content.size()
243  );
244  EXPECT_TRUE(folly::closeNoInt(fd) != -1);
245 
246  {
247  // it should fail to load
248  CacheType cache(filename, cacheCapacity, chrono::seconds(1));
249  EXPECT_EQ(cache.size(), 0);
250 
251  // .. but new entries should work
252  cache.put("key1", "value1");
253  cache.put("key2", "value2");
254  EXPECT_EQ(cache.size(), 2);
255  EXPECT_EQ(cache.get("key1").value(), "value1");
256  EXPECT_EQ(cache.get("key2").value(), "value2");
257  }
258  {
259  // new format persists
260  CacheType cache(filename, cacheCapacity, chrono::seconds(1));
261  EXPECT_EQ(cache.size(), 2);
262  EXPECT_EQ(cache.get("key1").value(), "value1");
263  EXPECT_EQ(cache.get("key2").value(), "value2");
264  }
265  EXPECT_TRUE(unlink(filename.c_str()) != -1);
266 }
int closeNoInt(int fd)
Definition: FileUtil.cpp:56
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
KeyType
Definition: Signature.h:17
ssize_t writeFull(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:134
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
int openNoInt(const char *name, int flags, mode_t mode)
Definition: FileUtil.cpp:36
const char * string
Definition: Conv.cpp:212
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
std::vector< int > values(1'000)
TYPED_TEST ( FilePersistentCacheTest  ,
destroy   
)

Definition at line 268 of file FilePersistentCacheTest.cpp.

References wangle::getPersistentCacheFilename(), and string.

268  {
271 
272  auto cache1 = std::make_unique<CacheType>(
273  cacheFile, 10, std::chrono::seconds(3));
274  cache1.reset();
275  auto cache2 = std::make_unique<CacheType>(
276  cacheFile, 10, std::chrono::seconds(3));
277  cache2.reset();
278 }
const char * string
Definition: Conv.cpp:212
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
TYPED_TEST ( FilePersistentCacheTest  ,
threadstress   
)

Definition at line 280 of file FilePersistentCacheTest.cpp.

References b, EXPECT_EQ, EXPECT_TRUE, wangle::getPersistentCacheFilename(), i, threads, val, and folly::futures::Barrier::wait().

280  {
281  // make sure no errors crop up when hitting the same cache
282  // with multiple threads
283 
284  // spin up a few of threads that add and remove
285  // their own set of values on the same cache
287  auto cacheFile = getPersistentCacheFilename();
288  auto sharedCache = std::make_unique<CacheType>(
289  cacheFile, 10, std::chrono::seconds(10));
290 
291  int numThreads = 3;
292  Barrier b(numThreads);
293  auto threadFunc = [&b, numThreads](CacheType* cache, int tNum) {
294  auto key1 = folly::to<string>("key", tNum);
295  auto nextNum = (tNum + 1) % numThreads;
296  auto key2 = folly::to<string>("key", nextNum);
297  b.wait().get();
298  for (int i = 0; i < 100; ++i) {
299  cache->put(key1, i);
300  cache->put(key2, i);
301  cache->remove(key1);
302  cache->remove(key2);
303  }
304  // wait til everyone is done
305  b.wait().get();
306  cache->put(key1, tNum);
307  };
308 
309  std::vector<std::thread> threads;
310  for (int i = 0; i < numThreads; ++i) {
311  threads.push_back(std::thread(threadFunc, sharedCache.get(), i));
312  }
313  for (int i = 0; i < numThreads; ++i) {
314  threads[i].join();
315  }
316  EXPECT_EQ(sharedCache->size(), numThreads);
317  for (auto i = 0; i < numThreads; ++i) {
318  auto key = folly::to<string>("key", i);
319  auto val = sharedCache->get(key);
320  EXPECT_TRUE(val.hasValue());
321  EXPECT_EQ(*val, i);
322  }
323 }
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
double val
Definition: String.cpp:273
std::vector< std::thread::id > threads
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::string getPersistentCacheFilename()
Definition: TestUtil.cpp:22
TYPED_TEST_CASE ( FilePersistentCacheTest  ,
MutexTypes   
)