Autotest: fix a race condition in verifying a peer D-Bus connected
On the unit test side, everything is sequential: we first ask for the connection, verify that it is connected, then ask the remote side via the session bus if it is connected. Unfortunately, the remote site may handle things in a different order: it may handle the incoming function call to "isConnected" before doing accept(2) on the listening socket. So, instead, make the local side block until the connection is received on the other side. On the remote, we don't block, instead we use the feature of delayed replies. Change-Id: Ie386938b8b39dd94a9d7e5913668125fb4a3c7da Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
This commit is contained in:
parent
01fc82e357
commit
aa83bacb14
@ -72,9 +72,17 @@ public slots:
|
||||
return QDBusServer::address();
|
||||
}
|
||||
|
||||
bool isConnected() const
|
||||
void waitForConnected()
|
||||
{
|
||||
return m_conn.isConnected();
|
||||
if (callPendingReply.type() != QDBusMessage::InvalidMessage) {
|
||||
sendErrorReply(QDBusError::NotSupported, "One call already pending!");
|
||||
return;
|
||||
}
|
||||
if (m_conn.isConnected())
|
||||
return;
|
||||
// not connected, we'll reply later
|
||||
setDelayedReply(true);
|
||||
callPendingReply = message();
|
||||
}
|
||||
|
||||
Q_NOREPLY void requestSync(const QString &seq)
|
||||
@ -146,10 +154,16 @@ private slots:
|
||||
{
|
||||
m_conn = con;
|
||||
con.registerObject(objectPath, this, QDBusConnection::ExportScriptableSignals);
|
||||
|
||||
if (callPendingReply.type() != QDBusMessage::InvalidMessage) {
|
||||
QDBusConnection::sessionBus().send(callPendingReply.createReply());
|
||||
callPendingReply = QDBusMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QDBusConnection m_conn;
|
||||
QDBusMessage callPendingReply;
|
||||
MyObject* obj;
|
||||
};
|
||||
|
||||
|
@ -514,10 +514,9 @@ void tst_QDBusAbstractAdaptor::initTestCase()
|
||||
QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
|
||||
QVERIFY(peercon.isConnected());
|
||||
|
||||
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
|
||||
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "waitForConnected");
|
||||
QDBusMessage rpl2 = QDBusConnection::sessionBus().call(req2);
|
||||
QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
|
||||
QVERIFY(rpl2.arguments().at(0).toBool());
|
||||
QVERIFY2(rpl2.type() == QDBusMessage::ReplyMessage, rpl2.errorMessage().toLatin1());
|
||||
}
|
||||
|
||||
void tst_QDBusAbstractAdaptor::cleanupTestCase()
|
||||
|
@ -59,9 +59,17 @@ public slots:
|
||||
return QDBusServer::address();
|
||||
}
|
||||
|
||||
bool isConnected() const
|
||||
void waitForConnected()
|
||||
{
|
||||
return m_conn.isConnected();
|
||||
if (callPendingReply.type() != QDBusMessage::InvalidMessage) {
|
||||
sendErrorReply(QDBusError::NotSupported, "One call already pending!");
|
||||
return;
|
||||
}
|
||||
if (m_conn.isConnected())
|
||||
return;
|
||||
// not connected, we'll reply later
|
||||
setDelayedReply(true);
|
||||
callPendingReply = message();
|
||||
}
|
||||
|
||||
void reset()
|
||||
@ -97,11 +105,16 @@ private slots:
|
||||
{
|
||||
m_conn = con;
|
||||
m_conn.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents);
|
||||
if (callPendingReply.type() != QDBusMessage::InvalidMessage) {
|
||||
QDBusConnection::sessionBus().send(callPendingReply.createReply());
|
||||
callPendingReply = QDBusMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Interface targetObj;
|
||||
QDBusConnection m_conn;
|
||||
QDBusMessage callPendingReply;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -268,10 +268,9 @@ void tst_QDBusAbstractInterface::init()
|
||||
QDBusConnection peercon = QDBusConnection::connectToPeer(peerAddress, "peer");
|
||||
QVERIFY(peercon.isConnected());
|
||||
|
||||
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
|
||||
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "waitForConnected");
|
||||
QDBusMessage rpl2 = con.call(req2);
|
||||
QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
|
||||
QVERIFY(rpl2.arguments().at(0).toBool());
|
||||
QVERIFY2(rpl2.type() == QDBusMessage::ReplyMessage, rpl2.errorMessage().toLatin1());
|
||||
}
|
||||
|
||||
void tst_QDBusAbstractInterface::cleanup()
|
||||
|
@ -63,9 +63,17 @@ public slots:
|
||||
return QDBusServer::address();
|
||||
}
|
||||
|
||||
bool isConnected() const
|
||||
void waitForConnected()
|
||||
{
|
||||
return m_conn.isConnected();
|
||||
if (callPendingReply.type() != QDBusMessage::InvalidMessage) {
|
||||
sendErrorReply(QDBusError::NotSupported, "One call already pending!");
|
||||
return;
|
||||
}
|
||||
if (m_conn.isConnected())
|
||||
return;
|
||||
// not connected, we'll reply later
|
||||
setDelayedReply(true);
|
||||
callPendingReply = message();
|
||||
}
|
||||
|
||||
void emitSignal(const QString &interface, const QString &name, const QString &arg)
|
||||
@ -123,10 +131,15 @@ private slots:
|
||||
m_conn.registerObject("/", &obj, QDBusConnection::ExportAllProperties
|
||||
| QDBusConnection::ExportAllSlots
|
||||
| QDBusConnection::ExportAllInvokables);
|
||||
if (callPendingReply.type() != QDBusMessage::InvalidMessage) {
|
||||
QDBusConnection::sessionBus().send(callPendingReply.createReply());
|
||||
callPendingReply = QDBusMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QDBusConnection m_conn;
|
||||
QDBusMessage callPendingReply;
|
||||
MyObject obj;
|
||||
};
|
||||
|
||||
|
@ -290,10 +290,10 @@ void tst_QDBusInterface::initTestCase()
|
||||
QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
|
||||
QVERIFY(peercon.isConnected());
|
||||
|
||||
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected");
|
||||
QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "waitForConnected");
|
||||
QDBusMessage rpl2 = con.call(req2);
|
||||
QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage);
|
||||
QVERIFY(rpl2.arguments().at(0).toBool());
|
||||
QVERIFY2(rpl2.type() == QDBusMessage::ReplyMessage, rpl2.errorMessage().toLatin1());
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::cleanupTestCase()
|
||||
|
Loading…
Reference in New Issue
Block a user