Added Test Cases for PeriodicTask
This commit is contained in:
parent
77b67a8137
commit
1f14598d25
@ -9,17 +9,18 @@ namespace caching {
|
||||
|
||||
PeriodicTask::PeriodicTask(function<void ()> task, double intervalSec) : _thread(), _task(task), _intervalSec(intervalSec) {
|
||||
_thread = boost::thread([this]() {
|
||||
boost::chrono::nanoseconds interval((uint64_t)(UINT64_C(1000000000) * _intervalSec));
|
||||
try {
|
||||
boost::chrono::nanoseconds interval((uint64_t)(UINT64_C(1000000000) * _intervalSec));
|
||||
try {
|
||||
while(true) {
|
||||
boost::this_thread::sleep_for(interval);
|
||||
_task();
|
||||
}
|
||||
} catch (const boost::thread_interrupted &e) {
|
||||
//Do nothing, exit thread.
|
||||
} catch (...) {
|
||||
cerr << "PeriodicTask crashed" << endl;
|
||||
}
|
||||
} catch (const boost::thread_interrupted &e) {
|
||||
//Do nothing, exit thread.
|
||||
} catch (...) {
|
||||
//TODO Think about logging
|
||||
cerr << "PeriodicTask crashed" << endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
namespace blockstore {
|
||||
namespace caching {
|
||||
|
||||
//TODO Test cases
|
||||
class PeriodicTask {
|
||||
public:
|
||||
PeriodicTask(std::function<void ()> task, double intervalSec);
|
||||
|
63
test/implementations/caching/PeriodicTaskTest.cpp
Normal file
63
test/implementations/caching/PeriodicTaskTest.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
|
||||
#include "../../../implementations/caching/PeriodicTask.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
|
||||
using ::testing::Test;
|
||||
using std::mutex;
|
||||
using std::unique_lock;
|
||||
using std::condition_variable;
|
||||
|
||||
using namespace blockstore::caching;
|
||||
|
||||
class AtomicCounter {
|
||||
public:
|
||||
AtomicCounter(int count): _mutex(), _cv(), _counter(count) {}
|
||||
|
||||
void decrease() {
|
||||
unique_lock<mutex> lock(_mutex);
|
||||
--_counter;
|
||||
_cv.notify_all();
|
||||
}
|
||||
|
||||
void waitForZero() {
|
||||
unique_lock<mutex> lock(_mutex);
|
||||
_cv.wait(lock, [this] () {return _counter <= 0;});
|
||||
}
|
||||
private:
|
||||
mutex _mutex;
|
||||
condition_variable _cv;
|
||||
int _counter;
|
||||
};
|
||||
|
||||
class PeriodicTaskTest: public Test {
|
||||
};
|
||||
|
||||
TEST_F(PeriodicTaskTest, DoesntDeadlockInDestructorWhenDestructedImmediately) {
|
||||
PeriodicTask task([](){}, 1);
|
||||
}
|
||||
|
||||
TEST_F(PeriodicTaskTest, CallsCallbackAtLeast10Times) {
|
||||
AtomicCounter counter(10);
|
||||
|
||||
PeriodicTask task([&counter](){
|
||||
counter.decrease();
|
||||
}, 0.001);
|
||||
|
||||
counter.waitForZero();
|
||||
}
|
||||
|
||||
TEST_F(PeriodicTaskTest, DoesntCallCallbackAfterDestruction) {
|
||||
std::atomic<int> callCount(0);
|
||||
{
|
||||
PeriodicTask task([&callCount](){
|
||||
callCount += 1;
|
||||
}, 0.001);
|
||||
}
|
||||
int callCountDirectlyAfterDestruction = callCount;
|
||||
boost::this_thread::sleep_for(boost::chrono::seconds(1));
|
||||
EXPECT_EQ(callCountDirectlyAfterDestruction, callCount);
|
||||
}
|
Loading…
Reference in New Issue
Block a user