Removed hard unit tests for executor && fixed another tests

git-svn-id: svn://db.shs.com.ru/pip@890 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
4 changed files with 17 additions and 172 deletions

View File

@@ -10,56 +10,48 @@
#include "testutil.h" #include "testutil.h"
class ConditionLock : public ::testing::Test, public TestUtil { class ConditionLock : public ::testing::Test, public TestUtil {
protected: public:
void TearDown() override { PIConditionLock* m = new PIConditionLock();
if (adapter != nullptr) delete adapter;
}
}; };
TEST_F(ConditionLock, lock_is_protect) { TEST_F(ConditionLock, lock_is_protect) {
PIConditionLock m; m->lock();
m.lock();
bool isProtect = true; bool isProtect = true;
createThread([&](){ createThread([&](){
m.lock(); m->lock();
isProtect = false; isProtect = false;
}); });
ASSERT_TRUE(isProtect); ASSERT_TRUE(isProtect);
} }
TEST_F(ConditionLock, unlock_is_release) { TEST_F(ConditionLock, unlock_is_release) {
PIConditionLock m; m->lock();
m.lock();
volatile bool isReleased = false; volatile bool isReleased = false;
m.unlock(); m->unlock();
createThread([&](){ createThread([&](){
m.lock(); m->lock();
isReleased = true; isReleased = true;
m.unlock(); m->unlock();
}); });
EXPECT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); EXPECT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS));
ASSERT_TRUE(isReleased); ASSERT_TRUE(isReleased);
} }
TEST_F(ConditionLock, tryLock_is_false_when_locked) { TEST_F(ConditionLock, tryLock_is_false_when_locked) {
PIConditionLock m;
createThread([&](){ createThread([&](){
m.lock(); m->lock();
piMSleep(WAIT_THREAD_TIME_MS); piMSleep(WAIT_THREAD_TIME_MS);
}); });
ASSERT_FALSE(m.tryLock()); ASSERT_FALSE(m->tryLock());
} }
TEST_F(ConditionLock, tryLock_is_true_when_unlocked) { TEST_F(ConditionLock, tryLock_is_true_when_unlocked) {
PIConditionLock m; ASSERT_TRUE(m->tryLock());
ASSERT_TRUE(m.tryLock());
} }
TEST_F(ConditionLock, tryLock_is_recursive_lock_enable) { TEST_F(ConditionLock, tryLock_is_recursive_lock_enable) {
PIConditionLock m; m->lock();
m.lock(); ASSERT_TRUE(m->tryLock());
ASSERT_TRUE(m.tryLock());
} }

View File

@@ -23,21 +23,8 @@ protected:
m.unlock(); m.unlock();
}; };
} }
void TearDown() override {
if (adapter != nullptr) delete adapter;
}
}; };
TEST(ThreadFuncAdapter, registerToInvoke_is_stdFun_invoke) {
bool isInvoke = false;
StdFunctionThreadFuncAdapter adapter([&](){
isInvoke = true;
});
adapter.threadFunc()(adapter.data());
ASSERT_TRUE(isInvoke);
}
TEST_F(ConditionVariable, wait_is_block) { TEST_F(ConditionVariable, wait_is_block) {
createThread(); createThread();
ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS));
@@ -62,12 +49,10 @@ TEST_F(ConditionVariable, wait_is_unblock_when_notifyOne_after_wait) {
} }
TEST_F(ConditionVariable, wait_is_unblock_when_notifyAll_after_wait) { TEST_F(ConditionVariable, wait_is_unblock_when_notifyAll_after_wait) {
PIVector<StdFunctionThreadFuncAdapter*> adapters;
PIVector<PIThread*> threads; PIVector<PIThread*> threads;
for (int i = 0; i < THREAD_COUNT; ++i) { for (int i = 0; i < THREAD_COUNT; ++i) {
adapters.push_back(new StdFunctionThreadFuncAdapter(adapterFunctionDefault)); threads.push_back(new PIThread([=](){ adapterFunctionDefault(); }));
threads.push_back(new PIThread(adapters.back()->data(), adapters.back()->threadFunc()));
} }
piForeach(PIThread* thread, threads) thread->startOnce(); piForeach(PIThread* thread, threads) thread->startOnce();
@@ -80,16 +65,13 @@ TEST_F(ConditionVariable, wait_is_unblock_when_notifyAll_after_wait) {
} }
for (size_t i = 0; i < threads.size(); ++i) EXPECT_FALSE(threads[i]->isRunning()) << "Thread " << i << " still running"; for (size_t i = 0; i < threads.size(); ++i) EXPECT_FALSE(threads[i]->isRunning()) << "Thread " << i << " still running";
piForeach(PIThread* thread, threads) delete thread; piForeach(PIThread* thread, threads) delete thread;
piForeach(StdFunctionThreadFuncAdapter* adapter, adapters) delete adapter;
} }
TEST_F(ConditionVariable, wait_is_one_unblock_when_notifyOne) { TEST_F(ConditionVariable, wait_is_one_unblock_when_notifyOne) {
PIVector<StdFunctionThreadFuncAdapter*> adapters;
PIVector<PIThread*> threads; PIVector<PIThread*> threads;
for (int i = 0; i < THREAD_COUNT; ++i) { for (int i = 0; i < THREAD_COUNT; ++i) {
adapters.push_back(new StdFunctionThreadFuncAdapter(adapterFunctionDefault)); threads.push_back(new PIThread(adapterFunctionDefault));
threads.push_back(new PIThread(adapters.back()->data(), adapters.back()->threadFunc()));
} }
piForeach(PIThread* thread, threads) thread->startOnce(); piForeach(PIThread* thread, threads) thread->startOnce();

View File

@@ -1,127 +0,0 @@
//
// Created by fomenko on 23.09.2019.
//
#include "executor.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
using ::testing::_;
using ::testing::SetArgReferee;
using ::testing::DoAll;
using ::testing::DeleteArg;
using ::testing::Return;
using ::testing::AtLeast;
using ::testing::ByRef;
using ::testing::Eq;
typedef std::function<void()> VoidFunc;
namespace std {
inline bool operator ==(const VoidFunc& s, const VoidFunc& v) {
// TODO VoidFunc operator ==
return true;
}
}
const int THREAD_COUNT = 2;
class MockThread : public AbstractThread {
public:
MOCK_METHOD0(start, bool());
MOCK_METHOD0(stop, void());
MOCK_METHOD1(waitForStart, bool(int timeout_msecs));
MOCK_METHOD1(waitForFinish, bool(int timeout_msecs));
};
class MockDeque : public PIBlockingDequeue<VoidFunc> {
public:
MOCK_METHOD1(offer, bool(const VoidFunc&));
MOCK_METHOD0(take, VoidFunc());
MOCK_METHOD2(poll, VoidFunc(int timeoutMs, const VoidFunc& defaultVal));
MOCK_METHOD0(capacity, size_t());
MOCK_METHOD0(remainingCapacity, size_t());
};
class MockThreadFactory : public PIThreadFactory {
public:
int callCount = 0;
PIVector<MockThread*> threads;
std::function<void(MockThread*)> checkThreadExpectations = [](MockThread* thread){
EXPECT_CALL(*thread, start())
.WillOnce(Return(true));
EXPECT_CALL(*thread, stop())
.WillOnce(Return());
};
std::function<void(const VoidFunc& fun)> checkThreadFunc = [](const VoidFunc& fun) { };
AbstractThread* newThread(const VoidFunc& fun) override {
callCount++;
auto* thread = new MockThread();
threads.push_back(thread);
checkThreadExpectations(thread);
checkThreadFunc(fun);
return threads.back();
}
};
TEST(ExecutorUnitTest, is_corePool_created) {
auto* deque = new MockDeque();
auto* threadFactory = new MockThreadFactory();
PIThreadPoolExecutor executor(THREAD_COUNT, deque, threadFactory);
ASSERT_EQ(THREAD_COUNT, threadFactory->callCount);
}
TEST(ExecutorUnitTest, is_corePool_started) {
auto* deque = new MockDeque();
auto* threadFactory = new MockThreadFactory();
PIThreadPoolExecutor executor(THREAD_COUNT, deque, threadFactory);
}
TEST(ExecutorUnitTest, execute_is_added_to_taskQueue) {
VoidFunc voidFunc = [](){};
auto* deque = new MockDeque();
EXPECT_CALL(*deque, offer(Eq(voidFunc)))
.WillOnce(Return(true));
auto* threadFactory = new MockThreadFactory();
PIThreadPoolExecutor executor(THREAD_COUNT, deque, threadFactory);
executor.execute([]() {});
}
TEST(ExecutorUnitTest, is_corePool_execute_queue_elements) {
auto* deque = new MockDeque();
auto* threadFactory = new MockThreadFactory();
threadFactory->checkThreadFunc = [](const VoidFunc& fun) {
fun();
};
ON_CALL(*deque, take())
.WillByDefault(Return([](){}));
EXPECT_CALL(*deque, poll(_, _))
.Times(THREAD_COUNT)
.WillRepeatedly(Return([](){}));
PIThreadPoolExecutor executor(THREAD_COUNT, deque, threadFactory);
}
TEST(ExecutorUnitTest, shutdown_is_stop_threads) {
auto* deque = new MockDeque();
auto* threadFactory = new MockThreadFactory();
PIVector<VoidFunc> threadFuncs;
threadFactory->checkThreadExpectations = [](MockThread* thread) {
EXPECT_CALL(*thread, start())
.WillOnce(Return(true));
EXPECT_CALL(*thread, stop())
.WillRepeatedly(Return());
};
threadFactory->checkThreadFunc = [&](const VoidFunc& threadFunc) { threadFuncs.push_back(threadFunc); };
ON_CALL(*deque, take())
.WillByDefault(Return(VoidFunc()));
EXPECT_CALL(*deque, poll(_, _))
.Times(THREAD_COUNT)
.WillRepeatedly(Return(VoidFunc()));
PIThreadPoolExecutor executor(THREAD_COUNT, deque, threadFactory);
executor.shutdown();
piForeachC(VoidFunc& threadFunc, threadFuncs) threadFunc();
}

View File

@@ -20,15 +20,13 @@ PIOBJECT(TestUtil)
public: public:
double threadStartTime; double threadStartTime;
PIThread* thread = new PIThread(); PIThread* thread = new PIThread();
StdFunctionThreadFuncAdapter* adapter = nullptr;
volatile bool isRunning; volatile bool isRunning;
std::function<void()> adapterFunctionDefault; std::function<void()> adapterFunctionDefault;
bool createThread(const std::function<void()>& fun = nullptr, PIThread* thread_ = nullptr) { bool createThread(const std::function<void()>& fun = nullptr, PIThread* thread_ = nullptr) {
adapter = new StdFunctionThreadFuncAdapter(fun == nullptr ? adapterFunctionDefault : fun); std::function<void()> actualFun = fun == nullptr ? adapterFunctionDefault : fun;
if (thread_ == nullptr) thread_ = thread; if (thread_ == nullptr) thread_ = thread;
adapter->registerToInvoke(thread_); thread_->startOnce([=](void*){ actualFun(); });
thread_->startOnce();
return waitThread(thread_); return waitThread(thread_);
} }