2015-04-28 11:56:07 +02:00
|
|
|
#include "testutils/CacheTest.h"
|
|
|
|
|
|
|
|
#include "../../../../implementations/caching/cache/Cache.h"
|
|
|
|
#include "testutils/MinimalKeyType.h"
|
|
|
|
#include "testutils/MinimalValueType.h"
|
2015-08-31 23:04:56 +02:00
|
|
|
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
2015-04-28 11:56:07 +02:00
|
|
|
|
|
|
|
using ::testing::Test;
|
|
|
|
|
|
|
|
using namespace blockstore::caching;
|
|
|
|
|
|
|
|
class CacheTest_PushAndPop: public CacheTest {};
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, PopNonExistingEntry_EmptyCache) {
|
|
|
|
EXPECT_EQ(boost::none, pop(10));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, PopNonExistingEntry_NonEmptyCache) {
|
|
|
|
push(9, 10);
|
|
|
|
EXPECT_EQ(boost::none, pop(10));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, PopNonExistingEntry_FullCache) {
|
|
|
|
//Add a lot of even numbered keys
|
2015-05-08 02:10:56 +02:00
|
|
|
for (unsigned int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(2*i, 2*i);
|
|
|
|
}
|
|
|
|
//Request an odd numbered key
|
|
|
|
EXPECT_EQ(boost::none, pop(9));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, OneEntry) {
|
|
|
|
push(10, 20);
|
|
|
|
EXPECT_EQ(20, pop(10).value());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, MultipleEntries) {
|
|
|
|
push(10, 20);
|
|
|
|
push(20, 30);
|
|
|
|
push(30, 40);
|
|
|
|
EXPECT_EQ(30, pop(20).value());
|
|
|
|
EXPECT_EQ(20, pop(10).value());
|
|
|
|
EXPECT_EQ(40, pop(30).value());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, FullCache) {
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(i, 2*i);
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, FullCache_PushNonOrdered_PopOrdered) {
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 1; i < Cache::MAX_ENTRIES; i += 2) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(i, 2*i);
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; i += 2) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(i, 2*i);
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, FullCache_PushOrdered_PopNonOrdered) {
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(i, 2*i);
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 1; i < Cache::MAX_ENTRIES; i += 2) {
|
2015-04-28 11:56:07 +02:00
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; i += 2) {
|
2015-04-28 11:56:07 +02:00
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int roundDownToEven(int number) {
|
|
|
|
if (number % 2 == 0) {
|
|
|
|
return number;
|
|
|
|
} else {
|
|
|
|
return number - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int roundDownToOdd(int number) {
|
|
|
|
if (number % 2 != 0) {
|
|
|
|
return number;
|
|
|
|
} else {
|
|
|
|
return number - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, FullCache_PushNonOrdered_PopNonOrdered) {
|
|
|
|
for(int i = roundDownToEven(Cache::MAX_ENTRIES - 1); i >= 0; i -= 2) {
|
|
|
|
push(i, 2*i);
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 1; i < Cache::MAX_ENTRIES; i += 2) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(i, 2*i);
|
|
|
|
}
|
|
|
|
for(int i = roundDownToOdd(Cache::MAX_ENTRIES-1); i >= 0; i -= 2) {
|
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES; i += 2) {
|
2015-04-28 11:56:07 +02:00
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, MoreThanFullCache) {
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 0; i < Cache::MAX_ENTRIES + 2; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
push(i, 2*i);
|
|
|
|
}
|
|
|
|
//Check that the oldest two elements got deleted automatically
|
|
|
|
EXPECT_EQ(boost::none, pop(0));
|
|
|
|
EXPECT_EQ(boost::none, pop(1));
|
|
|
|
//Check the other elements are still there
|
2015-05-08 02:10:56 +02:00
|
|
|
for(unsigned int i = 2; i < Cache::MAX_ENTRIES + 2; ++i) {
|
2015-04-28 11:56:07 +02:00
|
|
|
EXPECT_EQ(2*i, pop(i).value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CacheTest_PushAndPop, AfterTimeout) {
|
|
|
|
constexpr double TIMEOUT1_SEC = Cache::MAX_LIFETIME_SEC * 3/4;
|
|
|
|
constexpr double TIMEOUT2_SEC = Cache::PURGE_LIFETIME_SEC * 3/4;
|
|
|
|
static_assert(TIMEOUT1_SEC + TIMEOUT2_SEC > Cache::MAX_LIFETIME_SEC, "Ensure that our chosen timeouts push the first entry out of the cache");
|
|
|
|
|
|
|
|
push(10, 20);
|
|
|
|
boost::this_thread::sleep_for(boost::chrono::milliseconds(static_cast<int>(1000 * TIMEOUT1_SEC)));
|
|
|
|
push(20, 30);
|
|
|
|
boost::this_thread::sleep_for(boost::chrono::milliseconds(static_cast<int>(1000 * TIMEOUT2_SEC)));
|
|
|
|
EXPECT_EQ(boost::none, pop(10));
|
|
|
|
EXPECT_EQ(30, pop(20).value());
|
|
|
|
}
|