Added test cases for Cache
This commit is contained in:
parent
d589910b0d
commit
cb402fd14b
14
test/implementations/caching/cache/CacheTest.cpp
vendored
14
test/implementations/caching/cache/CacheTest.cpp
vendored
@ -1,14 +0,0 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
|
||||
#include "../../../../implementations/caching/cache/Cache.h"
|
||||
|
||||
using ::testing::Test;
|
||||
|
||||
using namespace blockstore::caching;
|
||||
|
||||
class CacheTest: public Test {
|
||||
public:
|
||||
Cache<int, int> cache;
|
||||
};
|
||||
|
||||
//TODO Write test cases
|
34
test/implementations/caching/cache/CacheTest_MoveConstructor.cpp
vendored
Normal file
34
test/implementations/caching/cache/CacheTest_MoveConstructor.cpp
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
#include <memory>
|
||||
#include "../../../../implementations/caching/cache/Cache.h"
|
||||
#include "testutils/MinimalKeyType.h"
|
||||
#include "testutils/CopyableMovableValueType.h"
|
||||
|
||||
using namespace blockstore::caching;
|
||||
|
||||
using ::testing::Test;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
|
||||
//Test that Cache uses a move constructor for Value if possible
|
||||
class CacheTest_MoveConstructor: public Test {
|
||||
public:
|
||||
CacheTest_MoveConstructor() {
|
||||
CopyableMovableValueType::numCopyConstructorCalled = 0;
|
||||
cache = make_unique<Cache<MinimalKeyType, CopyableMovableValueType>>();
|
||||
}
|
||||
unique_ptr<Cache<MinimalKeyType, CopyableMovableValueType>> cache;
|
||||
};
|
||||
|
||||
TEST_F(CacheTest_MoveConstructor, MoveIntoCache) {
|
||||
cache->push(MinimalKeyType::create(0), CopyableMovableValueType(2));
|
||||
CopyableMovableValueType val = cache->pop(MinimalKeyType::create(0)).value();
|
||||
EXPECT_EQ(0, CopyableMovableValueType::numCopyConstructorCalled);
|
||||
}
|
||||
|
||||
TEST_F(CacheTest_MoveConstructor, CopyIntoCache) {
|
||||
CopyableMovableValueType value(2);
|
||||
cache->push(MinimalKeyType::create(0), value);
|
||||
CopyableMovableValueType val = cache->pop(MinimalKeyType::create(0)).value();
|
||||
EXPECT_EQ(1, CopyableMovableValueType::numCopyConstructorCalled);
|
||||
}
|
133
test/implementations/caching/cache/CacheTest_PushAndPop.cpp
vendored
Normal file
133
test/implementations/caching/cache/CacheTest_PushAndPop.cpp
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
#include "testutils/CacheTest.h"
|
||||
|
||||
#include "../../../../implementations/caching/cache/Cache.h"
|
||||
#include "testutils/MinimalKeyType.h"
|
||||
#include "testutils/MinimalValueType.h"
|
||||
|
||||
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
|
||||
for (int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
||||
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) {
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
||||
push(i, 2*i);
|
||||
}
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
||||
EXPECT_EQ(2*i, pop(i).value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CacheTest_PushAndPop, FullCache_PushNonOrdered_PopOrdered) {
|
||||
for(int i = 1; i < Cache::MAX_ENTRIES; i += 2) {
|
||||
push(i, 2*i);
|
||||
}
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; i += 2) {
|
||||
push(i, 2*i);
|
||||
}
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
||||
EXPECT_EQ(2*i, pop(i).value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CacheTest_PushAndPop, FullCache_PushOrdered_PopNonOrdered) {
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; ++i) {
|
||||
push(i, 2*i);
|
||||
}
|
||||
for(int i = 1; i < Cache::MAX_ENTRIES; i += 2) {
|
||||
EXPECT_EQ(2*i, pop(i).value());
|
||||
}
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; i += 2) {
|
||||
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);
|
||||
}
|
||||
for(int i = 1; i < Cache::MAX_ENTRIES; i += 2) {
|
||||
push(i, 2*i);
|
||||
}
|
||||
for(int i = roundDownToOdd(Cache::MAX_ENTRIES-1); i >= 0; i -= 2) {
|
||||
EXPECT_EQ(2*i, pop(i).value());
|
||||
}
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES; i += 2) {
|
||||
EXPECT_EQ(2*i, pop(i).value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CacheTest_PushAndPop, MoreThanFullCache) {
|
||||
for(int i = 0; i < Cache::MAX_ENTRIES + 2; ++i) {
|
||||
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
|
||||
for(int i = 2; i < Cache::MAX_ENTRIES + 2; ++i) {
|
||||
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());
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#include <memory>
|
||||
#include "../../../../implementations/caching/cache/QueueMap.h"
|
||||
#include "testutils/MinimalKeyType.h"
|
||||
#include "testutils/CopyableMovableValueType.h"
|
||||
|
||||
using namespace blockstore::caching;
|
||||
|
||||
@ -9,56 +10,38 @@ using ::testing::Test;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
|
||||
class CopyableValueType {
|
||||
public:
|
||||
static int numCopyConstructorCalled;
|
||||
CopyableValueType(int value): _value(value) {}
|
||||
CopyableValueType(const CopyableValueType &rhs): CopyableValueType(rhs._value) {
|
||||
++numCopyConstructorCalled;
|
||||
}
|
||||
CopyableValueType(CopyableValueType &&rhs): CopyableValueType(rhs._value) {
|
||||
//Don't increase numCopyConstructorCalled
|
||||
}
|
||||
int value() const {
|
||||
return _value;
|
||||
}
|
||||
private:
|
||||
int _value;
|
||||
};
|
||||
int CopyableValueType::numCopyConstructorCalled = 0;
|
||||
|
||||
//Test that QueueMap uses a move constructor for Value if possible
|
||||
class QueueMapTest_MoveConstructor: public Test {
|
||||
public:
|
||||
QueueMapTest_MoveConstructor() {
|
||||
CopyableValueType::numCopyConstructorCalled = 0;
|
||||
map = make_unique<QueueMap<MinimalKeyType, CopyableValueType>>();
|
||||
CopyableMovableValueType::numCopyConstructorCalled = 0;
|
||||
map = make_unique<QueueMap<MinimalKeyType, CopyableMovableValueType>>();
|
||||
}
|
||||
unique_ptr<QueueMap<MinimalKeyType, CopyableValueType>> map;
|
||||
unique_ptr<QueueMap<MinimalKeyType, CopyableMovableValueType>> map;
|
||||
};
|
||||
|
||||
TEST_F(QueueMapTest_MoveConstructor, PushingAndPopping_MoveIntoMap) {
|
||||
map->push(MinimalKeyType::create(0), CopyableValueType(2));
|
||||
CopyableValueType val = map->pop().value();
|
||||
EXPECT_EQ(0, CopyableValueType::numCopyConstructorCalled);
|
||||
map->push(MinimalKeyType::create(0), CopyableMovableValueType(2));
|
||||
CopyableMovableValueType val = map->pop().value();
|
||||
EXPECT_EQ(0, CopyableMovableValueType::numCopyConstructorCalled);
|
||||
}
|
||||
|
||||
TEST_F(QueueMapTest_MoveConstructor, PushingAndPoppingPerKey_MoveIntoMap) {
|
||||
map->push(MinimalKeyType::create(0), CopyableValueType(2));
|
||||
CopyableValueType val = map->pop(MinimalKeyType::create(0)).value();
|
||||
EXPECT_EQ(0, CopyableValueType::numCopyConstructorCalled);
|
||||
map->push(MinimalKeyType::create(0), CopyableMovableValueType(2));
|
||||
CopyableMovableValueType val = map->pop(MinimalKeyType::create(0)).value();
|
||||
EXPECT_EQ(0, CopyableMovableValueType::numCopyConstructorCalled);
|
||||
}
|
||||
|
||||
TEST_F(QueueMapTest_MoveConstructor, PushingAndPopping_CopyIntoMap) {
|
||||
CopyableValueType value(2);
|
||||
CopyableMovableValueType value(2);
|
||||
map->push(MinimalKeyType::create(0), value);
|
||||
CopyableValueType val = map->pop().value();
|
||||
EXPECT_EQ(1, CopyableValueType::numCopyConstructorCalled);
|
||||
CopyableMovableValueType val = map->pop().value();
|
||||
EXPECT_EQ(1, CopyableMovableValueType::numCopyConstructorCalled);
|
||||
}
|
||||
|
||||
TEST_F(QueueMapTest_MoveConstructor, PushingAndPoppingPerKey_CopyIntoMap) {
|
||||
CopyableValueType value(2);
|
||||
CopyableMovableValueType value(2);
|
||||
map->push(MinimalKeyType::create(0), value);
|
||||
CopyableValueType val = map->pop(MinimalKeyType::create(0)).value();
|
||||
EXPECT_EQ(1, CopyableValueType::numCopyConstructorCalled);
|
||||
CopyableMovableValueType val = map->pop(MinimalKeyType::create(0)).value();
|
||||
EXPECT_EQ(1, CopyableMovableValueType::numCopyConstructorCalled);
|
||||
}
|
||||
|
13
test/implementations/caching/cache/testutils/CacheTest.cpp
vendored
Normal file
13
test/implementations/caching/cache/testutils/CacheTest.cpp
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#include "CacheTest.h"
|
||||
|
||||
void CacheTest::push(int key, int value) {
|
||||
return _cache.push(MinimalKeyType::create(key), MinimalValueType::create(value));
|
||||
}
|
||||
|
||||
boost::optional<int> CacheTest::pop(int key) {
|
||||
boost::optional<MinimalValueType> entry = _cache.pop(MinimalKeyType::create(key));
|
||||
if (!entry) {
|
||||
return boost::none;
|
||||
}
|
||||
return entry->value();
|
||||
}
|
25
test/implementations/caching/cache/testutils/CacheTest.h
vendored
Normal file
25
test/implementations/caching/cache/testutils/CacheTest.h
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#ifndef BLOCKS_MESSMER_BLOCKSTORE_TEST_IMPLEMENTATIONS_CACHING_CACHE_TESTUTILS_QUEUEMAPTEST_H_
|
||||
#define BLOCKS_MESSMER_BLOCKSTORE_TEST_IMPLEMENTATIONS_CACHING_CACHE_TESTUTILS_QUEUEMAPTEST_H_
|
||||
|
||||
#include <google/gtest/gtest.h>
|
||||
#include "../../../../../implementations/caching/cache/Cache.h"
|
||||
#include "MinimalKeyType.h"
|
||||
#include "MinimalValueType.h"
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
// This class is a parent class for tests on QueueMap.
|
||||
// It offers functions to work with a QueueMap test object which is built using types having only the minimal type requirements.
|
||||
// Furthermore, the class checks that there are no memory leaks left after destructing the QueueMap (by counting leftover instances of Keys/Values).
|
||||
class CacheTest: public ::testing::Test {
|
||||
public:
|
||||
void push(int key, int value);
|
||||
boost::optional<int> pop(int key);
|
||||
|
||||
using Cache = blockstore::caching::Cache<MinimalKeyType, MinimalValueType>;
|
||||
|
||||
private:
|
||||
Cache _cache;
|
||||
};
|
||||
|
||||
#endif
|
3
test/implementations/caching/cache/testutils/CopyableMovableValueType.cpp
vendored
Normal file
3
test/implementations/caching/cache/testutils/CopyableMovableValueType.cpp
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#include "CopyableMovableValueType.h"
|
||||
|
||||
int CopyableMovableValueType::numCopyConstructorCalled = 0;
|
23
test/implementations/caching/cache/testutils/CopyableMovableValueType.h
vendored
Normal file
23
test/implementations/caching/cache/testutils/CopyableMovableValueType.h
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_BLOCKSTORE_TEST_IMPLEMENTATIONS_CACHING_CACHE_TESTUTILS_COPYABLEMOVABLEVALUETYPE_H_
|
||||
#define MESSMER_BLOCKSTORE_TEST_IMPLEMENTATIONS_CACHING_CACHE_TESTUTILS_COPYABLEMOVABLEVALUETYPE_H_
|
||||
|
||||
class CopyableMovableValueType {
|
||||
public:
|
||||
static int numCopyConstructorCalled;
|
||||
CopyableMovableValueType(int value): _value(value) {}
|
||||
CopyableMovableValueType(const CopyableMovableValueType &rhs): CopyableMovableValueType(rhs._value) {
|
||||
++numCopyConstructorCalled;
|
||||
}
|
||||
CopyableMovableValueType(CopyableMovableValueType &&rhs): CopyableMovableValueType(rhs._value) {
|
||||
//Don't increase numCopyConstructorCalled
|
||||
}
|
||||
int value() const {
|
||||
return _value;
|
||||
}
|
||||
private:
|
||||
int _value;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user