diff options
author | George Kiagiadakis <george.kiagiadakis@collabora.com> | 2012-04-10 20:44:48 +0300 |
---|---|---|
committer | George Kiagiadakis <george.kiagiadakis@collabora.com> | 2012-04-10 22:10:38 +0300 |
commit | 11feef12ef5138c703f9974bbd9a35c670cfcc76 (patch) | |
tree | a7d4967a7cccc5fb2e849f4291b34791a60ffbe8 /tests/lib | |
parent | a1e4147a4677293164eed80e056f812309c6a33a (diff) |
tests-lib: Add a new TestThreadHelper class
This class allows us to run parts of a unit test in a different thread context,
while being in sync with the unit test flow. This is useful to run connection
manager implementations in a different thread, to overcome the shortcomings
of the QtDBus local-loop optimizations.
Diffstat (limited to 'tests/lib')
-rw-r--r-- | tests/lib/CMakeLists.txt | 22 | ||||
-rw-r--r-- | tests/lib/test-thread-helper.cpp | 36 | ||||
-rw-r--r-- | tests/lib/test-thread-helper.h | 77 |
3 files changed, 133 insertions, 2 deletions
diff --git a/tests/lib/CMakeLists.txt b/tests/lib/CMakeLists.txt index 2a96336f..1755ddc3 100644 --- a/tests/lib/CMakeLists.txt +++ b/tests/lib/CMakeLists.txt @@ -1,9 +1,27 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}) +set(tp_qt_tests_SRCS + test.cpp + test-thread-helper.cpp +) + +set(tp_qt_tests_MOC_SRCS + test.h + test-thread-helper.h +) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_gen") -tpqt_generate_moc_i(test.h ${CMAKE_CURRENT_BINARY_DIR}/_gen/test.h.moc.hpp) -add_library(tp-qt-tests test.cpp ${CMAKE_CURRENT_BINARY_DIR}/_gen/test.h.moc.hpp) + +foreach(moc_src ${tp_qt_tests_MOC_SRCS}) + set(generated_file _gen/${moc_src}) + string(REPLACE ".h" ".h.moc.hpp" generated_file ${generated_file}) + tpqt_generate_moc_i(${CMAKE_CURRENT_SOURCE_DIR}/${moc_src} + ${CMAKE_CURRENT_BINARY_DIR}/${generated_file}) + list(APPEND tp_qt_tests_SRCS ${CMAKE_CURRENT_BINARY_DIR}/${generated_file}) +endforeach(moc_src ${tp_qt_tests_MOC_SRCS}) + +add_library(tp-qt-tests ${tp_qt_tests_SRCS}) target_link_libraries(tp-qt-tests ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} telepathy-qt${QT_VERSION_MAJOR}) if(ENABLE_TP_GLIB_TESTS) diff --git a/tests/lib/test-thread-helper.cpp b/tests/lib/test-thread-helper.cpp new file mode 100644 index 00000000..d2148d2a --- /dev/null +++ b/tests/lib/test-thread-helper.cpp @@ -0,0 +1,36 @@ +#include "tests/lib/test-thread-helper.h" +#include <QEventLoop> + +TestThreadHelperBase::TestThreadHelperBase(ThreadObjectBase *threadObject) +{ + Q_ASSERT(threadObject); + + mThread = new QThread; + mThreadObject = threadObject; + mThreadObject->moveToThread(mThread); + + QEventLoop loop; + QObject::connect(mThread, SIGNAL(started()), &loop, SLOT(quit())); + QMetaObject::invokeMethod(mThread, "start"); + loop.exec(); +} + +TestThreadHelperBase::~TestThreadHelperBase() +{ + QMetaObject::invokeMethod(mThreadObject, "deleteLater"); + mThread->quit(); + mThread->wait(); + mThread->deleteLater(); + QCoreApplication::processEvents(); +} + +void TestThreadHelperBase::executeCallback() +{ + QEventLoop loop; + QObject::connect(mThreadObject, SIGNAL(callbackExecutionFinished()), + &loop, SLOT(quit())); + QMetaObject::invokeMethod(mThreadObject, "executeCallback"); + loop.exec(); +} + +#include "_gen/test-thread-helper.h.moc.hpp" diff --git a/tests/lib/test-thread-helper.h b/tests/lib/test-thread-helper.h new file mode 100644 index 00000000..3d483ed7 --- /dev/null +++ b/tests/lib/test-thread-helper.h @@ -0,0 +1,77 @@ +#ifndef _TelepathyQt_tests_lib_test_thread_helper_h_HEADER_GUARD_ +#define _TelepathyQt_tests_lib_test_thread_helper_h_HEADER_GUARD_ + +#include <QObject> +#include <QThread> +#include <QCoreApplication> +#include <TelepathyQt/Callbacks> + +class ThreadObjectBase : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + virtual void executeCallback() = 0; + +Q_SIGNALS: + void callbackExecutionFinished(); +}; + +template <typename Context> +class ThreadObject : public ThreadObjectBase +{ +public: + typedef Tp::Callback1<void, Context&> Callback; + Callback mCallback; + + virtual void executeCallback() + { + Q_ASSERT(mCallback.isValid()); + Q_ASSERT(QThread::currentThread() != QCoreApplication::instance()->thread()); + + mCallback(mContext); + Q_EMIT callbackExecutionFinished(); + } + +private: + Context mContext; +}; + +class TestThreadHelperBase +{ +public: + virtual ~TestThreadHelperBase(); + +protected: + TestThreadHelperBase(ThreadObjectBase *threadObject); + void executeCallback(); + +protected: + QThread *mThread; + ThreadObjectBase *mThreadObject; +}; + +template <typename Context> +class TestThreadHelper : public TestThreadHelperBase +{ +public: + TestThreadHelper() + : TestThreadHelperBase(new ThreadObject<Context>()) + { } + + void executeCallback(typename ThreadObject<Context>::Callback const & cb) + { + static_cast<ThreadObject<Context>*>(mThreadObject)->mCallback = cb; + TestThreadHelperBase::executeCallback(); + } +}; + +#define TEST_THREAD_HELPER_EXECUTE(helper, callback) \ + do { \ + (helper)->executeCallback(Tp::ptrFun(callback)); \ + if (QTest::currentTestFailed()) { \ + return; \ + } \ + } while(0) + +#endif // _TelepathyQt_tests_lib_test_thread_helper_h_HEADER_GUARD_ |