summaryrefslogtreecommitdiff
path: root/tests/lib
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2012-04-10 20:44:48 +0300
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2012-04-10 22:10:38 +0300
commit11feef12ef5138c703f9974bbd9a35c670cfcc76 (patch)
treea7d4967a7cccc5fb2e849f4291b34791a60ffbe8 /tests/lib
parenta1e4147a4677293164eed80e056f812309c6a33a (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.txt22
-rw-r--r--tests/lib/test-thread-helper.cpp36
-rw-r--r--tests/lib/test-thread-helper.h77
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_