summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TelepathyQt/base-connection.cpp8
-rw-r--r--TelepathyQt/connection-manager.cpp15
-rw-r--r--TelepathyQt/dbus-service.cpp4
-rw-r--r--tests/dbus/CMakeLists.txt4
-rw-r--r--tests/dbus/base-cm.cpp171
-rw-r--r--tests/lib/CMakeLists.txt22
-rw-r--r--tests/lib/test-thread-helper.cpp37
-rw-r--r--tests/lib/test-thread-helper.h77
8 files changed, 325 insertions, 13 deletions
diff --git a/TelepathyQt/base-connection.cpp b/TelepathyQt/base-connection.cpp
index c3b93b20..45389c58 100644
--- a/TelepathyQt/base-connection.cpp
+++ b/TelepathyQt/base-connection.cpp
@@ -187,10 +187,10 @@ bool BaseConnection::registerObject(DBusError *error)
QString escapedProtocolName = mPriv->protocolName;
escapedProtocolName.replace(QLatin1Char('-'), QLatin1Char('_'));
QString name = uniqueName();
- QString busName = QString(QLatin1String("%s.%s.%s.%s"))
- .arg(TP_QT_CONNECTION_BUS_NAME_BASE).arg(mPriv->cmName).arg(escapedProtocolName).arg(name);
- QString objectPath = QString(QLatin1String("%s/%s/%s/%s"))
- .arg(TP_QT_CONNECTION_OBJECT_PATH_BASE).arg(mPriv->cmName).arg(escapedProtocolName).arg(name);
+ QString busName = QString(QLatin1String("%1.%2.%3.%4"))
+ .arg(TP_QT_CONNECTION_BUS_NAME_BASE, mPriv->cmName, escapedProtocolName, name);
+ QString objectPath = QString(QLatin1String("%1/%2/%3/%4"))
+ .arg(TP_QT_CONNECTION_OBJECT_PATH_BASE, mPriv->cmName, escapedProtocolName, name);
DBusError _error;
bool ret = registerObject(busName, objectPath, &_error);
if (!ret && error) {
diff --git a/TelepathyQt/connection-manager.cpp b/TelepathyQt/connection-manager.cpp
index 5418bbf2..96b32348 100644
--- a/TelepathyQt/connection-manager.cpp
+++ b/TelepathyQt/connection-manager.cpp
@@ -1046,12 +1046,17 @@ void ConnectionManager::gotProtocolsLegacy(QDBusPendingCallWatcher *watcher)
debug() << "Got reply to ConnectionManager.ListProtocols";
protocolsNames = reply.value();
- foreach (const QString &protocolName, protocolsNames) {
- mPriv->protocols.append(ProtocolInfo(ConnectionManagerPtr(this), protocolName));
- mPriv->parametersQueue.enqueue(protocolName);
- }
+ if (!protocolsNames.isEmpty()) {
+ foreach (const QString &protocolName, protocolsNames) {
+ mPriv->protocols.append(ProtocolInfo(ConnectionManagerPtr(this), protocolName));
+ mPriv->parametersQueue.enqueue(protocolName);
+ }
- mPriv->introspectParametersLegacy();
+ mPriv->introspectParametersLegacy();
+ } else {
+ //no protocols - introspection finished
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
+ }
} else {
mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false, reply.error());
diff --git a/TelepathyQt/dbus-service.cpp b/TelepathyQt/dbus-service.cpp
index a22c6569..6a8f978f 100644
--- a/TelepathyQt/dbus-service.cpp
+++ b/TelepathyQt/dbus-service.cpp
@@ -167,7 +167,7 @@ bool DBusService::registerObject(const QString &busName, const QString &objectPa
if (!mPriv->dbusObject->dbusConnection().registerService(busName)) {
error->set(TP_QT_ERROR_INVALID_ARGUMENT,
- QString(QLatin1String("Name %s already in use by another process"))
+ QString(QLatin1String("Name %1 already in use by another process"))
.arg(busName));
warning() << "Unable to register service" << busName <<
"- name already registered by another process";
@@ -176,7 +176,7 @@ bool DBusService::registerObject(const QString &busName, const QString &objectPa
if (!mPriv->dbusObject->dbusConnection().registerObject(objectPath, mPriv->dbusObject)) {
error->set(TP_QT_ERROR_INVALID_ARGUMENT,
- QString(QLatin1String("Object at path %s already registered"))
+ QString(QLatin1String("Object at path %1 already registered"))
.arg(objectPath));
warning() << "Unable to register object" << objectPath <<
"- path already registered";
diff --git a/tests/dbus/CMakeLists.txt b/tests/dbus/CMakeLists.txt
index a7105488..5b87a6c1 100644
--- a/tests/dbus/CMakeLists.txt
+++ b/tests/dbus/CMakeLists.txt
@@ -83,6 +83,10 @@ tpqt_add_dbus_unit_test(CmProtocol cm-protocol)
tpqt_add_dbus_unit_test(ProfileManager profile-manager)
tpqt_add_dbus_unit_test(Types types)
+if(ENABLE_EXPERIMENTAL_SERVICE_SUPPORT)
+ tpqt_add_dbus_unit_test(BaseConnectionManager base-cm telepathy-qt${QT_VERSION_MAJOR}-service)
+endif(ENABLE_EXPERIMENTAL_SERVICE_SUPPORT)
+
# Make check target. In case of check, output on failure and put it into a log
# This target has to stay here for catching all of the tests
add_custom_target(check ctest --output-on-failure -O test.log
diff --git a/tests/dbus/base-cm.cpp b/tests/dbus/base-cm.cpp
new file mode 100644
index 00000000..b4809db9
--- /dev/null
+++ b/tests/dbus/base-cm.cpp
@@ -0,0 +1,171 @@
+#include <tests/lib/test.h>
+#include <tests/lib/test-thread-helper.h>
+
+#define TP_QT_ENABLE_LOWLEVEL_API
+
+#include <TelepathyQt/BaseConnectionManager>
+#include <TelepathyQt/BaseProtocol>
+#include <TelepathyQt/ConnectionManager>
+#include <TelepathyQt/ConnectionManagerLowlevel>
+#include <TelepathyQt/DBusError>
+#include <TelepathyQt/PendingReady>
+#include <TelepathyQt/PendingConnection>
+
+using namespace Tp;
+
+class TestBaseCM : public Test
+{
+ Q_OBJECT
+public:
+ TestBaseCM(QObject *parent = 0)
+ : Test(parent)
+ { }
+
+private Q_SLOTS:
+ void initTestCase();
+ void init();
+
+ void testNoProtocols();
+ void testProtocols();
+
+ void cleanup();
+ void cleanupTestCase();
+
+private:
+ static void testNoProtocolsCreateCM(BaseConnectionManagerPtr &cm);
+ static void testProtocolsCreateCM(BaseConnectionManagerPtr &cm);
+};
+
+void TestBaseCM::initTestCase()
+{
+ initTestCaseImpl();
+}
+
+void TestBaseCM::init()
+{
+ initImpl();
+}
+
+void TestBaseCM::testNoProtocolsCreateCM(BaseConnectionManagerPtr &cm)
+{
+ cm = BaseConnectionManager::create(QLatin1String("testcm"));
+ Tp::DBusError err;
+ QVERIFY(cm->registerObject(&err));
+ QVERIFY(!err.isValid());
+
+ QCOMPARE(cm->protocols().size(), 0);
+}
+
+void TestBaseCM::testNoProtocols()
+{
+ qDebug() << "Introspecting non-existing CM";
+
+ ConnectionManagerPtr cliCM = ConnectionManager::create(
+ QLatin1String("testcm"));
+ PendingReady *pr = cliCM->becomeReady(ConnectionManager::FeatureCore);
+ connect(pr, SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(expectFailure(Tp::PendingOperation*)));
+ QCOMPARE(mLoop->exec(), 0);
+
+ qDebug() << "Creating CM";
+
+ TestThreadHelper<BaseConnectionManagerPtr> helper;
+ TEST_THREAD_HELPER_EXECUTE(&helper, &testNoProtocolsCreateCM);
+
+ qDebug() << "Introspecting new CM";
+
+ cliCM = ConnectionManager::create(QLatin1String("testcm"));
+ pr = cliCM->becomeReady(ConnectionManager::FeatureCore);
+ connect(pr, SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(expectSuccessfulCall(Tp::PendingOperation*)));
+ QCOMPARE(mLoop->exec(), 0);
+
+ QCOMPARE(cliCM->supportedProtocols().size(), 0);
+
+ qDebug() << "Requesting connection";
+
+ PendingConnection *pc = cliCM->lowlevel()->requestConnection(
+ QLatin1String("jabber"), QVariantMap());
+ connect(pc, SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(expectFailure(Tp::PendingOperation*)));
+ QCOMPARE(mLoop->exec(), 0);
+ QCOMPARE(mLastError, TP_QT_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestBaseCM::testProtocolsCreateCM(BaseConnectionManagerPtr &cm)
+{
+ cm = BaseConnectionManager::create(QLatin1String("testcm"));
+
+ BaseProtocolPtr protocol = BaseProtocol::create(QLatin1String("myprotocol"));
+ QVERIFY(!protocol.isNull());
+ QVERIFY(cm->addProtocol(protocol));
+
+ QVERIFY(cm->hasProtocol(QLatin1String("myprotocol")));
+ QCOMPARE(cm->protocol(QLatin1String("myprotocol")), protocol);
+ QCOMPARE(cm->protocols().size(), 1);
+
+ QVERIFY(!cm->hasProtocol(QLatin1String("otherprotocol")));
+ QVERIFY(cm->protocol(QLatin1String("otherprotocol")).isNull());
+
+ //can't add the same protocol twice
+ QVERIFY(!cm->addProtocol(protocol));
+
+ Tp::DBusError err;
+ QVERIFY(cm->registerObject(&err));
+ QVERIFY(!err.isValid());
+
+ //can't add another protocol after registerObject()
+ protocol = BaseProtocol::create(QLatin1String("otherprotocol"));
+ QVERIFY(!protocol.isNull());
+ QVERIFY(!cm->addProtocol(protocol));
+ QCOMPARE(cm->protocols().size(), 1);
+ protocol.reset();
+
+ QVariantMap props = cm->immutableProperties();
+ QVERIFY(props.contains(TP_QT_IFACE_CONNECTION_MANAGER + QLatin1String(".Protocols")));
+
+ ProtocolPropertiesMap protocols = qvariant_cast<Tp::ProtocolPropertiesMap>(
+ props[TP_QT_IFACE_CONNECTION_MANAGER + QLatin1String(".Protocols")]);
+ QVERIFY(protocols.contains(QLatin1String("myprotocol")));
+ QVERIFY(!protocols.contains(QLatin1String("otherprotocol")));
+}
+
+void TestBaseCM::testProtocols()
+{
+ qDebug() << "Creating CM";
+
+ TestThreadHelper<BaseConnectionManagerPtr> helper;
+ TEST_THREAD_HELPER_EXECUTE(&helper, &testProtocolsCreateCM);
+
+ qDebug() << "Introspecting CM";
+
+ ConnectionManagerPtr cliCM = ConnectionManager::create(
+ QLatin1String("testcm"));
+ PendingReady *pr = cliCM->becomeReady(ConnectionManager::FeatureCore);
+ connect(pr, SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(expectSuccessfulCall(Tp::PendingOperation*)));
+ QCOMPARE(mLoop->exec(), 0);
+
+ QCOMPARE(cliCM->supportedProtocols().size(), 1);
+ QVERIFY(cliCM->hasProtocol(QLatin1String("myprotocol")));
+
+ PendingConnection *pc = cliCM->lowlevel()->requestConnection(
+ QLatin1String("myprotocol"), QVariantMap());
+ connect(pc, SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(expectFailure(Tp::PendingOperation*)));
+ QCOMPARE(mLoop->exec(), 0);
+ QCOMPARE(mLastError, TP_QT_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestBaseCM::cleanup()
+{
+ cleanupImpl();
+}
+
+void TestBaseCM::cleanupTestCase()
+{
+ cleanupTestCaseImpl();
+}
+
+QTEST_MAIN(TestBaseCM)
+#include "_gen/base-cm.cpp.moc.hpp"
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..a977c7a5
--- /dev/null
+++ b/tests/lib/test-thread-helper.cpp
@@ -0,0 +1,37 @@
+#include "tests/lib/test-thread-helper.h"
+#include <QEventLoop>
+#include <QTimer>
+
+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()));
+ QTimer::singleShot(0, mThread, SLOT(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_