1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
44
#include <qcoreapplication.h>
45
#include <qmetatype.h>
46
#include <QtTest/QtTest>
47
#include <QtCore/qvariant.h>
48
#include <QtDBus/QtDBus>
50
#include "../qdbusmarshall/common.h"
53
#define TEST_INTERFACE_NAME "org.qtproject.QtDBus.MyObject"
54
#define TEST_SIGNAL_NAME "somethingHappened"
56
static const char serviceName[] = "org.qtproject.autotests.qmyserver";
57
static const char objectPath[] = "/org/qtproject/qmyserver";
58
static const char *interfaceName = serviceName;
60
int MyObject::callCount = 0;
61
QVariantList MyObject::callArgs;
63
class MyObjectUnknownType: public QObject
66
Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject")
67
Q_CLASSINFO("D-Bus Introspection", ""
68
" <interface name=\"org.qtproject.QtDBus.MyObjectUnknownTypes\" >\n"
69
" <property access=\"readwrite\" type=\"~\" name=\"prop1\" />\n"
70
" <signal name=\"somethingHappened\" >\n"
71
" <arg direction=\"out\" type=\"~\" />\n"
73
" <method name=\"ping\" >\n"
74
" <arg direction=\"in\" type=\"~\" name=\"ping\" />\n"
75
" <arg direction=\"out\" type=\"~\" name=\"ping\" />\n"
77
" <method name=\"regularMethod\" />\n"
82
class Spy: public QObject
93
void spySlot(const QString& arg)
100
class DerivedFromQDBusInterface: public QDBusInterface
104
DerivedFromQDBusInterface()
105
: QDBusInterface("com.example.Test", "/")
113
void emitSignal(const QString &interface, const QString &name, const QString &arg)
115
QDBusMessage msg = QDBusMessage::createSignal("/", interface, name);
117
QDBusConnection::sessionBus().send(msg);
122
void emitSignalPeer(const QString &interface, const QString &name, const QString &arg)
124
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal");
128
QDBusConnection::sessionBus().send(req);
135
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callCount");
136
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
137
return reply.arguments().at(0).toInt();
140
QVariantList callArgsPeer()
142
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callArgs");
143
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
144
return qdbus_cast<QVariantList>(reply.arguments().at(0));
147
void setProp1Peer(int val)
149
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setProp1");
151
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
156
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "prop1");
157
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
158
return reply.arguments().at(0).toInt();
161
void setComplexPropPeer(QList<int> val)
163
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setComplexProp");
164
req << QVariant::fromValue(val);
165
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
168
QList<int> complexPropPeer()
170
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "complexProp");
171
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
172
return qdbus_cast<QList<int> >(reply.arguments().at(0));
177
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "reset");
178
QDBusConnection::sessionBus().call(req);
181
class tst_QDBusInterface: public QObject
187
void testServiceOwnerChanged(const QString &service)
189
if (service == "com.example.Test")
190
QTestEventLoop::instance().exitLoop();
195
void cleanupTestCase();
199
void notValidDerived();
200
void invalidAfterServiceOwnerChanged();
202
void introspectUnknownTypes();
203
void introspectVirtualObject();
206
void invokeMethodWithReturn();
207
void invokeMethodWithMultiReturn();
208
void invokeMethodWithComplexReturn();
210
void introspectPeer();
211
void callMethodPeer();
212
void invokeMethodPeer();
213
void invokeMethodWithReturnPeer();
214
void invokeMethodWithMultiReturnPeer();
215
void invokeMethodWithComplexReturnPeer();
221
void propertyWrite();
222
void complexPropertyRead();
223
void complexPropertyWrite();
225
void propertyReadPeer();
226
void propertyWritePeer();
227
void complexPropertyReadPeer();
228
void complexPropertyWritePeer();
233
class WaitForQMyServer: public QObject
240
void ownerChange(const QString &name)
242
if (name == serviceName)
250
WaitForQMyServer::WaitForQMyServer()
252
QDBusConnection con = QDBusConnection::sessionBus();
254
connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
255
SLOT(ownerChange(QString)));
256
QTimer::singleShot(2000, &loop, SLOT(quit()));
261
bool WaitForQMyServer::ok()
263
return QDBusConnection::sessionBus().isConnected() &&
264
QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName);
267
void tst_QDBusInterface::initTestCase()
269
QDBusConnection con = QDBusConnection::sessionBus();
270
QVERIFY(con.isConnected());
273
con.registerObject("/", &obj, QDBusConnection::ExportAllProperties
274
| QDBusConnection::ExportAllSlots
275
| QDBusConnection::ExportAllInvokables);
279
proc.start("qmyserver");
281
proc.start("./qmyserver/qmyserver");
283
QVERIFY(proc.waitForStarted());
287
//QTest::qWait(2000);
289
// get peer server address
290
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address");
291
QDBusMessage rpl = con.call(req);
292
QVERIFY(rpl.type() == QDBusMessage::ReplyMessage);
293
QString address = rpl.arguments().at(0).toString();
295
// connect to peer server
296
QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
297
QVERIFY(peercon.isConnected());
299
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
300
QDBusMessage rpl2 = con.call(req2);
301
QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
302
QVERIFY(rpl2.arguments().at(0).toBool());
305
void tst_QDBusInterface::cleanupTestCase()
311
void tst_QDBusInterface::notConnected()
313
QDBusConnection connection("");
314
QVERIFY(!connection.isConnected());
316
QDBusInterface interface("org.freedesktop.DBus", "/", "org.freedesktop.DBus",
319
QVERIFY(!interface.isValid());
320
QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
323
void tst_QDBusInterface::notValid()
325
QDBusConnection connection("");
326
QVERIFY(!connection.isConnected());
328
QDBusInterface interface("com.example.Test", QString(), "org.example.Test",
331
QVERIFY(!interface.isValid());
332
QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
335
void tst_QDBusInterface::notValidDerived()
337
DerivedFromQDBusInterface c;
338
QVERIFY(!c.isValid());
339
QMetaObject::invokeMethod(&c, "method", Qt::DirectConnection);
342
void tst_QDBusInterface::invalidAfterServiceOwnerChanged()
344
// this test is technically the same as tst_QDBusAbstractInterface::followSignal
345
QDBusConnection conn = QDBusConnection::sessionBus();
346
QDBusConnectionInterface *connIface = conn.interface();
348
QDBusInterface validInterface(conn.baseService(), "/");
349
QVERIFY(validInterface.isValid());
350
QDBusInterface invalidInterface("com.example.Test", "/");
351
QVERIFY(!invalidInterface.isValid());
353
QTestEventLoop::instance().connect(connIface, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
355
QVERIFY(connIface->registerService("com.example.Test") == QDBusConnectionInterface::ServiceRegistered);
357
QTestEventLoop::instance().enterLoop(5);
359
QVERIFY(!QTestEventLoop::instance().timeout());
360
QVERIFY(invalidInterface.isValid());
363
void tst_QDBusInterface::introspect()
365
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
366
TEST_INTERFACE_NAME);
368
const QMetaObject *mo = iface.metaObject();
370
QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
371
QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);
373
QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
374
QVERIFY(mo->indexOfProperty("prop1") != -1);
375
QVERIFY(mo->indexOfProperty("complexProp") != -1);
378
void tst_QDBusInterface::introspectUnknownTypes()
380
QDBusConnection con = QDBusConnection::sessionBus();
381
MyObjectUnknownType obj;
382
con.registerObject("/unknownTypes", &obj, QDBusConnection::ExportAllContents);
383
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/unknownTypes"),
384
"org.qtproject.QtDBus.MyObjectUnknownTypes");
386
const QMetaObject *mo = iface.metaObject();
387
QVERIFY(mo->indexOfMethod("regularMethod()") != -1); // this is the control
388
QVERIFY(mo->indexOfMethod("somethingHappened(QDBusRawType<0x7e>*)") != -1);
390
QVERIFY(mo->indexOfMethod("ping(QDBusRawType<0x7e>*)") != -1);
391
int midx = mo->indexOfMethod("ping(QDBusRawType<0x7e>*)");
392
QCOMPARE(mo->method(midx).typeName(), "QDBusRawType<0x7e>*");
394
QVERIFY(mo->indexOfProperty("prop1") != -1);
395
int pidx = mo->indexOfProperty("prop1");
396
QCOMPARE(mo->property(pidx).typeName(), "QDBusRawType<0x7e>*");
400
QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), "/unknownTypes", "org.freedesktop.DBus.Introspectable", "Introspect");
401
QDBusMessage reply = con.call(message, QDBus::Block, 5000);
402
qDebug() << "REPL: " << reply.arguments();
407
class VirtualObject: public QDBusVirtualObject
411
VirtualObject() :success(true) {}
413
QString introspect(const QString &path) const {
414
if (path == "/some/path/superNode")
415
return "zitroneneis";
416
if (path == "/some/path/superNode/foo")
417
return " <interface name=\"org.qtproject.QtDBus.VirtualObject\">\n"
418
" <method name=\"klingeling\" />\n"
423
bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
425
lastMessage = message;
428
QDBusMessage reply = message.createReply(replyArguments);
429
connection.send(reply);
431
emit messageReceived(message);
435
void messageReceived(const QDBusMessage &message) const;
438
mutable QDBusMessage lastMessage;
439
QVariantList replyArguments;
440
mutable int callCount;
444
void tst_QDBusInterface::introspectVirtualObject()
446
QDBusConnection con = QDBusConnection::sessionBus();
447
QVERIFY(con.isConnected());
452
QString path = "/some/path/superNode";
453
QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
455
QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, "org.freedesktop.DBus.Introspectable", "Introspect");
456
QDBusMessage reply = con.call(message, QDBus::Block, 5000);
457
QVERIFY(reply.arguments().at(0).toString().contains(
458
QRegExp("<node>.*zitroneneis.*<interface name=") ));
460
QDBusMessage message2 = QDBusMessage::createMethodCall(con.baseService(), path + "/foo", "org.freedesktop.DBus.Introspectable", "Introspect");
461
QDBusMessage reply2 = con.call(message2, QDBus::Block, 5000);
462
QVERIFY(reply2.arguments().at(0).toString().contains(
463
QRegExp("<node>.*<interface name=\"org.qtproject.QtDBus.VirtualObject\">"
464
".*<method name=\"klingeling\" />\n"
465
".*</interface>.*<interface name=") ));
468
void tst_QDBusInterface::callMethod()
470
QDBusConnection con = QDBusConnection::sessionBus();
471
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
472
TEST_INTERFACE_NAME);
474
MyObject::callCount = 0;
476
// call a SLOT method
477
QDBusMessage reply = iface.call("ping", QVariant::fromValue(QDBusVariant("foo")));
478
QCOMPARE(MyObject::callCount, 1);
479
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
481
// verify what the callee received
482
QCOMPARE(MyObject::callArgs.count(), 1);
483
QVariant v = MyObject::callArgs.at(0);
484
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
485
QCOMPARE(dv.variant().type(), QVariant::String);
486
QCOMPARE(dv.variant().toString(), QString("foo"));
489
QCOMPARE(reply.arguments().count(), 1);
490
v = reply.arguments().at(0);
491
dv = qdbus_cast<QDBusVariant>(v);
492
QCOMPARE(dv.variant().type(), QVariant::String);
493
QCOMPARE(dv.variant().toString(), QString("foo"));
495
// call an INVOKABLE method
496
reply = iface.call("ping_invokable", QVariant::fromValue(QDBusVariant("bar")));
497
QCOMPARE(MyObject::callCount, 2);
498
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
500
// verify what the callee received
501
QCOMPARE(MyObject::callArgs.count(), 1);
502
v = MyObject::callArgs.at(0);
503
dv = qdbus_cast<QDBusVariant>(v);
504
QCOMPARE(dv.variant().type(), QVariant::String);
505
QCOMPARE(dv.variant().toString(), QString("bar"));
508
QCOMPARE(reply.arguments().count(), 1);
509
v = reply.arguments().at(0);
510
dv = qdbus_cast<QDBusVariant>(v);
511
QCOMPARE(dv.variant().type(), QVariant::String);
512
QCOMPARE(dv.variant().toString(), QString("bar"));
515
void tst_QDBusInterface::invokeMethod()
517
QDBusConnection con = QDBusConnection::sessionBus();
518
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
519
TEST_INTERFACE_NAME);
521
MyObject::callCount = 0;
523
// make the SLOT call without a return type
524
QDBusVariant arg("foo");
525
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
526
QCOMPARE(MyObject::callCount, 1);
528
// verify what the callee received
529
QCOMPARE(MyObject::callArgs.count(), 1);
530
QVariant v = MyObject::callArgs.at(0);
531
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
532
QCOMPARE(dv.variant().type(), QVariant::String);
533
QCOMPARE(dv.variant().toString(), QString("foo"));
535
// make the INVOKABLE call without a return type
536
QDBusVariant arg2("bar");
537
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
538
QCOMPARE(MyObject::callCount, 2);
540
// verify what the callee received
541
QCOMPARE(MyObject::callArgs.count(), 1);
542
v = MyObject::callArgs.at(0);
543
dv = qdbus_cast<QDBusVariant>(v);
544
QCOMPARE(dv.variant().type(), QVariant::String);
545
QCOMPARE(dv.variant().toString(), QString("bar"));
548
void tst_QDBusInterface::invokeMethodWithReturn()
550
QDBusConnection con = QDBusConnection::sessionBus();
551
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
552
TEST_INTERFACE_NAME);
554
MyObject::callCount = 0;
557
// make the SLOT call without a return type
558
QDBusVariant arg("foo");
559
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
560
QCOMPARE(MyObject::callCount, 1);
562
// verify what the callee received
563
QCOMPARE(MyObject::callArgs.count(), 1);
564
QVariant v = MyObject::callArgs.at(0);
565
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
566
QCOMPARE(dv.variant().type(), QVariant::String);
567
QCOMPARE(dv.variant().toString(), arg.variant().toString());
569
// verify that we got the reply as expected
570
QCOMPARE(retArg.variant(), arg.variant());
572
// make the INVOKABLE call without a return type
573
QDBusVariant arg2("bar");
574
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
575
QCOMPARE(MyObject::callCount, 2);
577
// verify what the callee received
578
QCOMPARE(MyObject::callArgs.count(), 1);
579
v = MyObject::callArgs.at(0);
580
dv = qdbus_cast<QDBusVariant>(v);
581
QCOMPARE(dv.variant().type(), QVariant::String);
582
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
584
// verify that we got the reply as expected
585
QCOMPARE(retArg.variant(), arg2.variant());
588
void tst_QDBusInterface::invokeMethodWithMultiReturn()
590
QDBusConnection con = QDBusConnection::sessionBus();
591
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
592
TEST_INTERFACE_NAME);
594
MyObject::callCount = 0;
595
QDBusVariant retArg, retArg2;
597
// make the SLOT call without a return type
598
QDBusVariant arg("foo"), arg2("bar");
599
QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
600
Q_RETURN_ARG(QDBusVariant, retArg),
601
Q_ARG(QDBusVariant, arg),
602
Q_ARG(QDBusVariant, arg2),
603
Q_ARG(QDBusVariant&, retArg2)));
604
QCOMPARE(MyObject::callCount, 1);
606
// verify what the callee received
607
QCOMPARE(MyObject::callArgs.count(), 2);
608
QVariant v = MyObject::callArgs.at(0);
609
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
610
QCOMPARE(dv.variant().type(), QVariant::String);
611
QCOMPARE(dv.variant().toString(), arg.variant().toString());
613
v = MyObject::callArgs.at(1);
614
dv = qdbus_cast<QDBusVariant>(v);
615
QCOMPARE(dv.variant().type(), QVariant::String);
616
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
618
// verify that we got the replies as expected
619
QCOMPARE(retArg.variant(), arg.variant());
620
QCOMPARE(retArg2.variant(), arg2.variant());
622
// make the INVOKABLE call without a return type
623
QDBusVariant arg3("hello"), arg4("world");
624
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
625
Q_RETURN_ARG(QDBusVariant, retArg),
626
Q_ARG(QDBusVariant, arg3),
627
Q_ARG(QDBusVariant, arg4),
628
Q_ARG(QDBusVariant&, retArg2)));
629
QCOMPARE(MyObject::callCount, 2);
631
// verify what the callee received
632
QCOMPARE(MyObject::callArgs.count(), 2);
633
v = MyObject::callArgs.at(0);
634
dv = qdbus_cast<QDBusVariant>(v);
635
QCOMPARE(dv.variant().type(), QVariant::String);
636
QCOMPARE(dv.variant().toString(), arg3.variant().toString());
638
v = MyObject::callArgs.at(1);
639
dv = qdbus_cast<QDBusVariant>(v);
640
QCOMPARE(dv.variant().type(), QVariant::String);
641
QCOMPARE(dv.variant().toString(), arg4.variant().toString());
643
// verify that we got the replies as expected
644
QCOMPARE(retArg.variant(), arg3.variant());
645
QCOMPARE(retArg2.variant(), arg4.variant());
648
void tst_QDBusInterface::invokeMethodWithComplexReturn()
650
QDBusConnection con = QDBusConnection::sessionBus();
651
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
652
TEST_INTERFACE_NAME);
654
MyObject::callCount = 0;
657
// make the SLOT call without a return type
658
QList<int> arg = QList<int>() << 42 << -47;
659
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
660
QCOMPARE(MyObject::callCount, 1);
662
// verify what the callee received
663
QCOMPARE(MyObject::callArgs.count(), 1);
664
QVariant v = MyObject::callArgs.at(0);
665
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
666
QCOMPARE(qdbus_cast<QList<int> >(v), arg);
668
// verify that we got the reply as expected
669
QCOMPARE(retArg, arg);
671
// make the INVOKABLE call without a return type
672
QList<int> arg2 = QList<int>() << 24 << -74;
673
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
674
QCOMPARE(MyObject::callCount, 2);
676
// verify what the callee received
677
QCOMPARE(MyObject::callArgs.count(), 1);
678
v = MyObject::callArgs.at(0);
679
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
680
QCOMPARE(qdbus_cast<QList<int> >(v), arg2);
682
// verify that we got the reply as expected
683
QCOMPARE(retArg, arg2);
686
void tst_QDBusInterface::introspectPeer()
688
QDBusConnection con("peer");
689
QDBusInterface iface(QString(), QLatin1String("/"),
690
TEST_INTERFACE_NAME, con);
692
const QMetaObject *mo = iface.metaObject();
694
QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
695
QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);
697
QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
698
QVERIFY(mo->indexOfProperty("prop1") != -1);
699
QVERIFY(mo->indexOfProperty("complexProp") != -1);
702
void tst_QDBusInterface::callMethodPeer()
704
QDBusConnection con("peer");
705
QDBusInterface iface(QString(), QLatin1String("/"),
706
TEST_INTERFACE_NAME, con);
710
// call a SLOT method
711
QDBusMessage reply = iface.call("ping", QVariant::fromValue(QDBusVariant("foo")));
712
QCOMPARE(callCountPeer(), 1);
713
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
715
// verify what the callee received
716
QVariantList callArgs = callArgsPeer();
717
QCOMPARE(callArgs.count(), 1);
718
QVariant v = callArgs.at(0);
719
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
720
QCOMPARE(dv.variant().type(), QVariant::String);
721
QCOMPARE(dv.variant().toString(), QString("foo"));
724
QCOMPARE(reply.arguments().count(), 1);
725
v = reply.arguments().at(0);
726
dv = qdbus_cast<QDBusVariant>(v);
727
QCOMPARE(dv.variant().type(), QVariant::String);
728
QCOMPARE(dv.variant().toString(), QString("foo"));
730
// call an INVOKABLE method
731
reply = iface.call("ping_invokable", QVariant::fromValue(QDBusVariant("bar")));
732
QCOMPARE(callCountPeer(), 2);
733
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
735
// verify what the callee received
736
callArgs = callArgsPeer();
737
QCOMPARE(callArgs.count(), 1);
739
dv = qdbus_cast<QDBusVariant>(v);
740
QCOMPARE(dv.variant().type(), QVariant::String);
741
QCOMPARE(dv.variant().toString(), QString("bar"));
744
QCOMPARE(reply.arguments().count(), 1);
745
v = reply.arguments().at(0);
746
dv = qdbus_cast<QDBusVariant>(v);
747
QCOMPARE(dv.variant().type(), QVariant::String);
748
QCOMPARE(dv.variant().toString(), QString("bar"));
751
void tst_QDBusInterface::invokeMethodPeer()
753
QDBusConnection con("peer");
754
QDBusInterface iface(QString(), QLatin1String("/"),
755
TEST_INTERFACE_NAME, con);
759
// make the SLOT call without a return type
760
QDBusVariant arg("foo");
761
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
762
QCOMPARE(callCountPeer(), 1);
764
// verify what the callee received
765
QVariantList callArgs = callArgsPeer();
766
QCOMPARE(callArgs.count(), 1);
767
QVariant v = callArgs.at(0);
768
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
769
QCOMPARE(dv.variant().type(), QVariant::String);
770
QCOMPARE(dv.variant().toString(), QString("foo"));
772
// make the INVOKABLE call without a return type
773
QDBusVariant arg2("bar");
774
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
775
QCOMPARE(callCountPeer(), 2);
777
// verify what the callee received
778
callArgs = callArgsPeer();
779
QCOMPARE(callArgs.count(), 1);
781
dv = qdbus_cast<QDBusVariant>(v);
782
QCOMPARE(dv.variant().type(), QVariant::String);
783
QCOMPARE(dv.variant().toString(), QString("bar"));
786
void tst_QDBusInterface::invokeMethodWithReturnPeer()
788
QDBusConnection con("peer");
789
QDBusInterface iface(QString(), QLatin1String("/"),
790
TEST_INTERFACE_NAME, con);
795
// make the SLOT call without a return type
796
QDBusVariant arg("foo");
797
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
798
QCOMPARE(callCountPeer(), 1);
800
// verify what the callee received
801
QVariantList callArgs = callArgsPeer();
802
QCOMPARE(callArgs.count(), 1);
803
QVariant v = callArgs.at(0);
804
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
805
QCOMPARE(dv.variant().type(), QVariant::String);
806
QCOMPARE(dv.variant().toString(), arg.variant().toString());
808
// verify that we got the reply as expected
809
QCOMPARE(retArg.variant(), arg.variant());
811
// make the INVOKABLE call without a return type
812
QDBusVariant arg2("bar");
813
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
814
QCOMPARE(callCountPeer(), 2);
816
// verify what the callee received
817
callArgs = callArgsPeer();
818
QCOMPARE(callArgs.count(), 1);
820
dv = qdbus_cast<QDBusVariant>(v);
821
QCOMPARE(dv.variant().type(), QVariant::String);
822
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
824
// verify that we got the reply as expected
825
QCOMPARE(retArg.variant(), arg2.variant());
828
void tst_QDBusInterface::invokeMethodWithMultiReturnPeer()
830
QDBusConnection con("peer");
831
QDBusInterface iface(QString(), QLatin1String("/"),
832
TEST_INTERFACE_NAME, con);
835
QDBusVariant retArg, retArg2;
837
// make the SLOT call without a return type
838
QDBusVariant arg("foo"), arg2("bar");
839
QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
840
Q_RETURN_ARG(QDBusVariant, retArg),
841
Q_ARG(QDBusVariant, arg),
842
Q_ARG(QDBusVariant, arg2),
843
Q_ARG(QDBusVariant&, retArg2)));
844
QCOMPARE(callCountPeer(), 1);
846
// verify what the callee received
847
QVariantList callArgs = callArgsPeer();
848
QCOMPARE(callArgs.count(), 2);
849
QVariant v = callArgs.at(0);
850
QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
851
QCOMPARE(dv.variant().type(), QVariant::String);
852
QCOMPARE(dv.variant().toString(), arg.variant().toString());
855
dv = qdbus_cast<QDBusVariant>(v);
856
QCOMPARE(dv.variant().type(), QVariant::String);
857
QCOMPARE(dv.variant().toString(), arg2.variant().toString());
859
// verify that we got the replies as expected
860
QCOMPARE(retArg.variant(), arg.variant());
861
QCOMPARE(retArg2.variant(), arg2.variant());
863
// make the INVOKABLE call without a return type
864
QDBusVariant arg3("hello"), arg4("world");
865
QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
866
Q_RETURN_ARG(QDBusVariant, retArg),
867
Q_ARG(QDBusVariant, arg3),
868
Q_ARG(QDBusVariant, arg4),
869
Q_ARG(QDBusVariant&, retArg2)));
870
QCOMPARE(callCountPeer(), 2);
872
// verify what the callee received
873
callArgs = callArgsPeer();
874
QCOMPARE(callArgs.count(), 2);
876
dv = qdbus_cast<QDBusVariant>(v);
877
QCOMPARE(dv.variant().type(), QVariant::String);
878
QCOMPARE(dv.variant().toString(), arg3.variant().toString());
881
dv = qdbus_cast<QDBusVariant>(v);
882
QCOMPARE(dv.variant().type(), QVariant::String);
883
QCOMPARE(dv.variant().toString(), arg4.variant().toString());
885
// verify that we got the replies as expected
886
QCOMPARE(retArg.variant(), arg3.variant());
887
QCOMPARE(retArg2.variant(), arg4.variant());
890
void tst_QDBusInterface::invokeMethodWithComplexReturnPeer()
892
QDBusConnection con("peer");
893
QDBusInterface iface(QString(), QLatin1String("/"),
894
TEST_INTERFACE_NAME, con);
899
// make the SLOT call without a return type
900
QList<int> arg = QList<int>() << 42 << -47;
901
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
902
QCOMPARE(callCountPeer(), 1);
904
// verify what the callee received
905
QVariantList callArgs = callArgsPeer();
906
QCOMPARE(callArgs.count(), 1);
907
QVariant v = callArgs.at(0);
908
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
909
QCOMPARE(qdbus_cast<QList<int> >(v), arg);
911
// verify that we got the reply as expected
912
QCOMPARE(retArg, arg);
914
// make the INVOKABLE call without a return type
915
QList<int> arg2 = QList<int>() << 24 << -74;
916
QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
917
QCOMPARE(callCountPeer(), 2);
919
// verify what the callee received
920
callArgs = callArgsPeer();
921
QCOMPARE(callArgs.count(), 1);
923
QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
924
QCOMPARE(qdbus_cast<QList<int> >(v), arg2);
926
// verify that we got the reply as expected
927
QCOMPARE(retArg, arg2);
930
void tst_QDBusInterface::signal()
932
QDBusConnection con = QDBusConnection::sessionBus();
933
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
934
TEST_INTERFACE_NAME);
936
QString arg = "So long and thanks for all the fish";
939
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
941
emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
942
QCOMPARE(spy.count, 1);
943
QCOMPARE(spy.received, arg);
946
QDBusInterface iface2(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
947
TEST_INTERFACE_NAME);
950
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
951
spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
953
emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
954
QCOMPARE(spy.count, 2);
955
QCOMPARE(spy.received, arg);
960
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
961
spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
963
emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
964
QCOMPARE(spy.count, 1);
965
QCOMPARE(spy.received, arg);
966
QCOMPARE(spy2.count, 1);
967
QCOMPARE(spy2.received, arg);
971
void tst_QDBusInterface::signalPeer()
973
QDBusConnection con("peer");
974
QDBusInterface iface(QString(), QLatin1String("/"),
975
TEST_INTERFACE_NAME, con);
977
QString arg = "So long and thanks for all the fish";
980
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
982
emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
983
QCOMPARE(spy.count, 1);
984
QCOMPARE(spy.received, arg);
987
QDBusInterface iface2(QString(), QLatin1String("/"),
988
TEST_INTERFACE_NAME, con);
991
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
992
spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
994
emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
995
QCOMPARE(spy.count, 2);
996
QCOMPARE(spy.received, arg);
1001
spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
1002
spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
1004
emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
1005
QCOMPARE(spy.count, 1);
1006
QCOMPARE(spy.received, arg);
1007
QCOMPARE(spy2.count, 1);
1008
QCOMPARE(spy2.received, arg);
1012
void tst_QDBusInterface::propertyRead()
1014
QDBusConnection con = QDBusConnection::sessionBus();
1015
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
1016
TEST_INTERFACE_NAME);
1018
int arg = obj.m_prop1 = 42;
1019
MyObject::callCount = 0;
1021
QVariant v = iface.property("prop1");
1022
QVERIFY(v.isValid());
1023
QCOMPARE(v.userType(), int(QVariant::Int));
1024
QCOMPARE(v.toInt(), arg);
1025
QCOMPARE(MyObject::callCount, 1);
1028
void tst_QDBusInterface::propertyWrite()
1030
QDBusConnection con = QDBusConnection::sessionBus();
1031
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
1032
TEST_INTERFACE_NAME);
1036
MyObject::callCount = 0;
1038
QVERIFY(iface.setProperty("prop1", arg));
1039
QCOMPARE(MyObject::callCount, 1);
1040
QCOMPARE(obj.m_prop1, arg);
1043
void tst_QDBusInterface::complexPropertyRead()
1045
QDBusConnection con = QDBusConnection::sessionBus();
1046
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
1047
TEST_INTERFACE_NAME);
1049
QList<int> arg = obj.m_complexProp = QList<int>() << 42 << -47;
1050
MyObject::callCount = 0;
1052
QVariant v = iface.property("complexProp");
1053
QVERIFY(v.isValid());
1054
QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
1055
QCOMPARE(v.value<QList<int> >(), arg);
1056
QCOMPARE(MyObject::callCount, 1);
1059
void tst_QDBusInterface::complexPropertyWrite()
1061
QDBusConnection con = QDBusConnection::sessionBus();
1062
QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
1063
TEST_INTERFACE_NAME);
1065
QList<int> arg = QList<int>() << -47 << 42;
1066
obj.m_complexProp.clear();
1067
MyObject::callCount = 0;
1069
QVERIFY(iface.setProperty("complexProp", QVariant::fromValue(arg)));
1070
QCOMPARE(MyObject::callCount, 1);
1071
QCOMPARE(obj.m_complexProp, arg);
1074
void tst_QDBusInterface::propertyReadPeer()
1076
QDBusConnection con("peer");
1077
QDBusInterface iface(QString(), QLatin1String("/"),
1078
TEST_INTERFACE_NAME, con);
1084
QVariant v = iface.property("prop1");
1085
QVERIFY(v.isValid());
1086
QCOMPARE(v.userType(), int(QVariant::Int));
1087
QCOMPARE(v.toInt(), arg);
1088
QCOMPARE(callCountPeer(), 1);
1091
void tst_QDBusInterface::propertyWritePeer()
1093
QDBusConnection con("peer");
1094
QDBusInterface iface(QString(), QLatin1String("/"),
1095
TEST_INTERFACE_NAME, con);
1101
QVERIFY(iface.setProperty("prop1", arg));
1102
QCOMPARE(callCountPeer(), 1);
1103
QCOMPARE(prop1Peer(), arg);
1106
void tst_QDBusInterface::complexPropertyReadPeer()
1108
QDBusConnection con("peer");
1109
QDBusInterface iface(QString(), QLatin1String("/"),
1110
TEST_INTERFACE_NAME, con);
1113
QList<int> arg = QList<int>() << 42 << -47;
1114
setComplexPropPeer(arg);
1116
QVariant v = iface.property("complexProp");
1117
QVERIFY(v.isValid());
1118
QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
1119
QCOMPARE(v.value<QList<int> >(), arg);
1120
QCOMPARE(callCountPeer(), 1);
1123
void tst_QDBusInterface::complexPropertyWritePeer()
1125
QDBusConnection con("peer");
1126
QDBusInterface iface(QString(), QLatin1String("/"),
1127
TEST_INTERFACE_NAME, con);
1130
QList<int> arg = QList<int>() << -47 << 42;
1132
QVERIFY(iface.setProperty("complexProp", QVariant::fromValue(arg)));
1133
QCOMPARE(callCountPeer(), 1);
1134
QCOMPARE(complexPropPeer(), arg);
1137
QTEST_MAIN(tst_QDBusInterface)
1139
#include "tst_qdbusinterface.moc"