diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2011-02-10 13:38:35 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2011-02-17 15:02:14 (GMT) |
commit | 1d8ebff955d357d3723487308e2906a12c6c043b (patch) | |
tree | d784db01d966a536401f448182bfccad0f2f6816 /tests/auto/qdbusmarshall | |
parent | cc2db7a49c9208a00a913f7c4a410009814a5580 (diff) | |
download | Qt-1d8ebff955d357d3723487308e2906a12c6c043b.zip Qt-1d8ebff955d357d3723487308e2906a12c6c043b.tar.gz Qt-1d8ebff955d357d3723487308e2906a12c6c043b.tar.bz2 |
QtDBus: Make sure we can receive unknown types
We must make sure we advance the receiving iterator, or we end up in
an infinite loop.
Task-number: QTBUG-17476
Diffstat (limited to 'tests/auto/qdbusmarshall')
-rw-r--r-- | tests/auto/qdbusmarshall/test/test.pro | 3 | ||||
-rw-r--r-- | tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 107 |
2 files changed, 108 insertions, 2 deletions
diff --git a/tests/auto/qdbusmarshall/test/test.pro b/tests/auto/qdbusmarshall/test/test.pro index 8901999..71fc656 100644 --- a/tests/auto/qdbusmarshall/test/test.pro +++ b/tests/auto/qdbusmarshall/test/test.pro @@ -5,4 +5,5 @@ TARGET = ../tst_qdbusmarshall QT = core QT += dbus - +LIBS += $$QT_LIBS_DBUS +QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index c05e49c..0d28dbd 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -38,7 +38,6 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#define DBUS_API_SUBJECT_TO_CHANGE #include <QtCore/QtCore> #include <QtTest/QtTest> #include <QtDBus/QtDBus> @@ -47,6 +46,8 @@ #include "common.h" #include <limits> +#include <dbus/dbus.h> + static const char serviceName[] = "com.trolltech.autotests.qpong"; static const char objectPath[] = "/com/trolltech/qpong"; static const char *interfaceName = serviceName; @@ -88,6 +89,9 @@ private slots: void sendCallErrors_data(); void sendCallErrors(); + void receiveUnknownType_data(); + void receiveUnknownType(); + private: QProcess proc; }; @@ -938,5 +942,106 @@ void tst_QDBusMarshall::sendCallErrors() QCOMPARE(reply.errorMessage(), errorMsg); } +void tst_QDBusMarshall::receiveUnknownType_data() +{ + QTest::newRow("in-call"); + QTest::newRow("type-variant"); + QTest::newRow("type-array"); + QTest::newRow("type-struct"); + QTest::newRow("type-naked"); +} + +void tst_QDBusMarshall::receiveUnknownType() +{ +#ifndef DBUS_TYPE_UNIX_FD + QSKIP("Your system's D-Bus library is too old for this test", SkipAll); +#else + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + // this needs to be implemented in raw + // open a new connection to the bus daemon + DBusError error; + dbus_error_init(&error); + DBusConnection *rawcon = dbus_bus_get_private(DBUS_BUS_SESSION, &error); + QVERIFY2(rawcon, error.name); + + // check if this bus supports passing file descriptors + if (!dbus_connection_can_send_type(rawcon, DBUS_TYPE_UNIX_FD)) + QSKIP("Your session bus does not allow sending Unix file descriptors", SkipAll); + + if (qstrcmp(QTest::currentDataTag(), "in-call") == 0) { + // create a call back to us containing a file descriptor + DBusMessage *msg = dbus_message_new_method_call(con.baseService().toLatin1(), "/irrelevant/path", NULL, "irrelevantMethod"); + + int fd = fileno(stdout); + dbus_message_append_args(msg, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID); + + // try to send to us + DBusPendingCall *pending; + dbus_connection_send_with_reply(rawcon, msg, &pending, 1000); + dbus_message_unref(msg); + + // check that it got sent + while (dbus_connection_dispatch(rawcon) == DBUS_DISPATCH_DATA_REMAINS) + ; + + // now spin our event loop. We don't catch this call, so let's get the reply + QEventLoop loop; + QTimer::singleShot(200, &loop, SLOT(quit())); + loop.exec(); + + // now try to receive the reply + dbus_pending_call_block(pending); + msg = dbus_pending_call_steal_reply(pending); + dbus_pending_call_unref(pending); + QVERIFY(msg); + QCOMPARE(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_ERROR); + QCOMPARE(dbus_message_get_error_name(msg), "org.freedesktop.DBus.Error.UnknownObject"); + qDebug() << dbus_message_get_signature(msg); + } else { + // create a signal that we'll emit + static const char signalName[] = "signalName"; + static const char interfaceName[] = "local.interface.name"; + DBusMessage *msg = dbus_message_new_signal("/", interfaceName, signalName); + con.connect(dbus_bus_get_unique_name(rawcon), QString(), interfaceName, signalName, &QTestEventLoop::instance(), SLOT(exitLoop())); + + DBusMessageIter iter; + dbus_message_iter_init_append(msg, &iter); + int fd = fileno(stdout); + + if (qstrcmp(QTest::currentDataTag(), "type-naked") == 0) { + // send naked + dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd); + } else { + DBusMessageIter subiter; + if (qstrcmp(QTest::currentDataTag(), "type-variant") == 0) + dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, DBUS_TYPE_UNIX_FD_AS_STRING, &subiter); + else if (qstrcmp(QTest::currentDataTag(), "type-array") == 0) + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_UNIX_FD_AS_STRING, &subiter); + else if (qstrcmp(QTest::currentDataTag(), "type-struct") == 0) + dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, 0, &subiter); + dbus_message_iter_append_basic(&subiter, DBUS_TYPE_UNIX_FD, &fd); + dbus_message_iter_close_container(&iter, &subiter); + } + + // send it + dbus_connection_send(rawcon, msg, 0); + dbus_message_unref(msg); + + // check that it got sent + while (dbus_connection_dispatch(rawcon) == DBUS_DISPATCH_DATA_REMAINS) + ; + + // now let's see what happens + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + } + + dbus_connection_close(rawcon); + dbus_connection_unref(rawcon); +#endif +} + QTEST_MAIN(tst_QDBusMarshall) #include "tst_qdbusmarshall.moc" |