diff options
-rw-r--r-- | TelepathyQt/base-connection.cpp | 8 | ||||
-rw-r--r-- | TelepathyQt/connection-manager.cpp | 15 | ||||
-rw-r--r-- | TelepathyQt/dbus-service.cpp | 4 | ||||
-rw-r--r-- | tests/dbus/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tests/dbus/base-cm.cpp | 171 | ||||
-rw-r--r-- | tests/lib/CMakeLists.txt | 22 | ||||
-rw-r--r-- | tests/lib/test-thread-helper.cpp | 37 | ||||
-rw-r--r-- | tests/lib/test-thread-helper.h | 77 |
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_ |