From 3986be6d98a09fa7854744253864a9e57486bbcf Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 2 Jan 2017 12:47:31 +0100 Subject: Improve reliability of network bearer tests May of the tests initiate a scan / update of the network configuration and expect the API to deliver exactly one update. This turns out to be a race condition as the update may be emitted multiple times, as QNetworkConfigurationManagerPrivate::updateConfigurations() is called via posted events (queued signal emissions) from the bearer thread, and so after creating the spy we may receive an update from _before_ and end up emitting the signal multiple times. Task-number: QTQAINFRA-1040 Change-Id: I931e2907f0cb86d48b4ab1a8795d75206035ea11 Reviewed-by: Thiago Macieira --- .../bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp | 4 ++-- .../tst_qnetworkconfigurationmanager.cpp | 10 +++++----- .../bearer/qnetworksession/test/tst_qnetworksession.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'tests/auto/network') diff --git a/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp index 0a52dd0388..82fa5cab9c 100644 --- a/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp +++ b/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp @@ -114,7 +114,7 @@ void tst_QNetworkConfiguration::comparison() QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(QNetworkConfiguration::Discovered); QVERIFY(configs.count()); @@ -161,7 +161,7 @@ void tst_QNetworkConfiguration::isRoamingAvailable() //force update to get maximum list QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete foreach(QNetworkConfiguration c, configs) { diff --git a/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp b/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp index 838612f638..b251a65420 100644 --- a/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp +++ b/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp @@ -68,7 +68,7 @@ void tst_QNetworkConfigurationManager::allConfigurations() QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); @@ -145,7 +145,7 @@ void tst_QNetworkConfigurationManager::defaultConfiguration() QNetworkConfigurationManager manager; QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); QNetworkConfiguration defaultConfig = manager.defaultConfiguration(); @@ -175,7 +175,7 @@ void tst_QNetworkConfigurationManager::configurationFromIdentifier() //force an update to get maximum number of configs QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); @@ -203,7 +203,7 @@ protected: preScanConfigs = manager.allConfigurations(); QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete configs = manager.allConfigurations(); } public: @@ -229,7 +229,7 @@ void tst_QNetworkConfigurationManager::usedInThread() QList preScanConfigs = manager.allConfigurations(); QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); QCOMPARE(thread.configs, configs); //Don't compare pre scan configs, because these may be cached and therefore give different results diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp index 4ae511cf54..138a0859cd 100644 --- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp +++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp @@ -106,7 +106,7 @@ void tst_QNetworkSession::initTestCase() QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); lackeyDir = QFINDTESTDATA("lackey"); QVERIFY2(!lackeyDir.isEmpty(), qPrintable( @@ -1007,7 +1007,7 @@ QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfigur QSignalSpy updateSpy(&mgr, SIGNAL(updateCompleted())); mgr.updateConfigurations(); - QTRY_NOOP(updateSpy.count() == 1); + QTRY_NOOP(updateSpy.count() >= 1); if (updateSpy.count() != 1) { qDebug("tst_QNetworkSession::suitableConfiguration() failure: unable to update configurations"); return QNetworkConfiguration(); @@ -1052,7 +1052,7 @@ void updateConfigurations() QNetworkConfigurationManager mgr; QSignalSpy updateSpy(&mgr, SIGNAL(updateCompleted())); mgr.updateConfigurations(); - QTRY_NOOP(updateSpy.count() == 1); + QTRY_NOOP(updateSpy.count() >= 1); } // A convenience-function: updates and prints all available confiurations and their states -- cgit v1.2.3 From 4baf08653c69fe5a131dae4ea27ac4cd67743f6e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 14 Jan 2017 09:02:03 +0100 Subject: QHostAddress: add missing docs qHash(QHostAddress) was added in Qt 5.0 (at least the version with uint seed = 0). op==(QHostAddress::SpecialAddress, QHostAddress) was there since QHostAddress was added before public history. Since QHostAddress does not have a \since, the I did not supply one for op==, either. Since the equality operator did not have unit-tests, added one. Change-Id: I954a0df02464338f08a12ca58d4cc0ceb013e67a Reviewed-by: Thiago Macieira --- tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests/auto/network') diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 364e435d3d..a715c38f32 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -271,6 +271,7 @@ void tst_QHostAddress::specialAddresses() //check special address equal to itself (QTBUG-22898), note two overloads of operator== QVERIFY(QHostAddress(address) == QHostAddress(address)); QVERIFY(QHostAddress(address) == address); + QVERIFY(address == QHostAddress(address)); QVERIFY(!(QHostAddress(address) != QHostAddress(address))); QVERIFY(!(QHostAddress(address) != address)); -- cgit v1.2.3 From 19a1a0871d4a9081646925c422fe32e900846c2e Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Mon, 16 Jan 2017 21:43:12 +0100 Subject: QSslDiffieHellmanParameters: simplify defaultParameters() construction This commit simplifies defaultParameters() to simply construct an empty QSslDiffieHellmanParameters and assigning the DER-form of the DH parameters to QSslDiffieHellmanParametersPrivate's derData field. This creates a valid QSslDiffieHellmanParameters instance, but skips any potentially expensive verification steps. The previous implementation of defaultParameters() would use the public fromEncoded() method to construct an instance of the default parameters. This triggers a verification of the passed-in data, which can be expensive. To ensure our defaultParameters() QSslDiffieHellmanParameters instance does pass verification, this commit adds an autotest to verify that. Fixes QTBUG-57815. Change-Id: I6b1d9dbbfde526b232c319195ddbad42326be27c Task-number: QTBUG-57815 Reviewed-by: Timur Pocheptsov --- .../tst_qssldiffiehellmanparameters.cpp | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'tests/auto/network') diff --git a/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp b/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp index f3b9003fbb..ddf503eed6 100644 --- a/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp +++ b/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp @@ -42,6 +42,13 @@ #include #include +// Default DH parameters, exported by qssldiffiehellmanparameters.cpp. +QT_BEGIN_NAMESPACE +extern Q_AUTOTEST_EXPORT const char *qssl_dhparams_default_base64; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + class tst_QSslDiffieHellmanParameters : public QObject { Q_OBJECT @@ -54,6 +61,7 @@ private Q_SLOTS: void constructionPEM(); void unsafe512Bits(); void unsafeNonPrime(); + void defaultIsValid(); #endif }; @@ -157,6 +165,33 @@ void tst_QSslDiffieHellmanParameters::unsafeNonPrime() #endif } +void tst_QSslDiffieHellmanParameters::defaultIsValid() +{ + // The QSslDiffieHellmanParameters::defaultParameters() method takes a shortcut, + // by not verifying the passed-in parameters. Instead, it simply assigns the default + // DH parameters to the derData field of QSslDiffieHellmanParametersPrivate. + // + // This test ensures that our default parameters pass the internal verification tests + // by constructing, using fromEncoded(), a QSslDiffieHellmanParameters instance that + // we expect to be equivalent to the one returned by defaultParameters(). By using + // fromEncoded() we go through the internal verification mechanisms. Finally, to ensure + // the two instances are equivalent, we compare them. + + const auto dh = QSslDiffieHellmanParameters::fromEncoded( + QByteArray::fromBase64(QByteArray(qssl_dhparams_default_base64)), + QSsl::Der + ); + + const auto defaultdh = QSslDiffieHellmanParameters::defaultParameters(); + +#ifndef QT_NO_OPENSSL + QCOMPARE(dh.isEmpty(), false); + QCOMPARE(dh.isValid(), true); + QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); + QCOMPARE(dh, defaultdh); +#endif +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslDiffieHellmanParameters) -- cgit v1.2.3 From 45948967bd2442d27c7526ec6f74b0df3edbe40a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 23 Jan 2017 11:04:12 +0100 Subject: tst_QSocks5SocketEngine: Refactor tests Rewrite tcpSocketNonBlockingTest() and downloadBigFile() to use lambdas for the slots. This allows for removing the related member variables and slots of the test class and ensures no leaks of sockets or inconsistent values. Add an error handler printing the error message to the flaky downloadBigFile() test. Change-Id: Ieb64063c41e045a1a50a6d074bef01753ee319ef Reviewed-by: Timur Pocheptsov --- .../tst_qsocks5socketengine.cpp | 140 ++++++++------------- 1 file changed, 52 insertions(+), 88 deletions(-) (limited to 'tests/auto/network') diff --git a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp index c945d77cda..18da122000 100644 --- a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp +++ b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp @@ -54,7 +54,6 @@ class tst_QSocks5SocketEngine : public QObject, public QAbstractSocketEngineRece private slots: void initTestCase(); - void init(); void construction(); void errorTest_data(); void errorTest(); @@ -74,13 +73,6 @@ private slots: void incomplete(); protected slots: - void tcpSocketNonBlocking_hostFound(); - void tcpSocketNonBlocking_connected(); - void tcpSocketNonBlocking_closed(); - void tcpSocketNonBlocking_readyRead(); - void tcpSocketNonBlocking_bytesWritten(qint64); - void exitLoopSlot(); - void downloadBigFileSlot(); void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); private: @@ -89,11 +81,6 @@ private: void closeNotification() { } void exceptionNotification() { } void connectionNotification() { } - QTcpSocket *tcpSocketNonBlocking_socket; - QStringList tcpSocketNonBlocking_data; - qint64 tcpSocketNonBlocking_totalWritten; - QTcpSocket *tmpSocket; - qint64 bytesAvailable; }; class MiniSocks5ResponseHandler : public QObject @@ -153,12 +140,6 @@ void tst_QSocks5SocketEngine::initTestCase() QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); } -void tst_QSocks5SocketEngine::init() -{ - tmpSocket = 0; - bytesAvailable = 0; -} - //--------------------------------------------------------------------------- void tst_QSocks5SocketEngine::construction() { @@ -631,13 +612,27 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() { QSocks5SocketEngineHandler socks5; + qint64 tcpSocketNonBlocking_totalWritten = 0; + QStringList tcpSocketNonBlocking_data; QTcpSocket socket; - connect(&socket, SIGNAL(hostFound()), SLOT(tcpSocketNonBlocking_hostFound())); - connect(&socket, SIGNAL(connected()), SLOT(tcpSocketNonBlocking_connected())); - connect(&socket, SIGNAL(disconnected()), SLOT(tcpSocketNonBlocking_closed())); - connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(tcpSocketNonBlocking_bytesWritten(qint64))); - connect(&socket, SIGNAL(readyRead()), SLOT(tcpSocketNonBlocking_readyRead())); - tcpSocketNonBlocking_socket = &socket; + connect(&socket, &QAbstractSocket::hostFound, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + connect(&socket, &QAbstractSocket::connected, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + connect(&socket, &QIODevice::bytesWritten, + [&tcpSocketNonBlocking_totalWritten] (qint64 written) + { + tcpSocketNonBlocking_totalWritten += written; + QTestEventLoop::instance().exitLoop(); + }); + + connect(&socket, &QIODevice::readyRead, + [&tcpSocketNonBlocking_data, &socket] () + { + while (socket.canReadLine()) + tcpSocketNonBlocking_data.append(socket.readLine()); + QTestEventLoop::instance().exitLoop(); + }); // Connect socket.connectToHost(QtNetworkSettings::serverName(), 143); @@ -725,62 +720,50 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() QCOMPARE(socket.state(), QTcpSocket::UnconnectedState); } -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_hostFound() -{ - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_connected() -{ - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_readyRead() -{ - while (tcpSocketNonBlocking_socket->canReadLine()) - tcpSocketNonBlocking_data.append(tcpSocketNonBlocking_socket->readLine()); - - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_bytesWritten(qint64 written) -{ - tcpSocketNonBlocking_totalWritten += written; - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_closed() -{ -} - //---------------------------------------------------------------------------------- void tst_QSocks5SocketEngine::downloadBigFile() { QSocks5SocketEngineHandler socks5; - if (tmpSocket) - delete tmpSocket; - tmpSocket = new QTcpSocket; - - connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot())); - connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot())); - - tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80); + QTcpSocket socket; + qint64 bytesAvailable = 0; + connect(&socket, &QAbstractSocket::connected, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + connect(&socket, &QIODevice::readyRead, + [&socket, &bytesAvailable] () + { + const QByteArray tmp = socket.readAll(); + int correction = tmp.indexOf(char(0), 0); //skip header + if (correction == -1) + correction = 0; + bytesAvailable += (tmp.size() - correction); + if (bytesAvailable >= 10000000) + QTestEventLoop::instance().exitLoop(); + }); + + connect(&socket, QOverload::of(&QAbstractSocket::error), + [&socket] (QAbstractSocket::SocketError errorCode) + { + qWarning().noquote().nospace() << QTest::currentTestFunction() + << ": error " << errorCode << ": " << socket.errorString(); + }); + + socket.connectToHost(QtNetworkSettings::serverName(), 80); QTestEventLoop::instance().enterLoop(30); if (QTestEventLoop::instance().timeout()) QFAIL("Network operation timed out"); QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); - QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); - QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); - QVERIFY(tmpSocket->write("HOST: ") > 0); - QVERIFY(tmpSocket->write(hostName.data()) > 0); - QVERIFY(tmpSocket->write("\r\n") > 0); - QVERIFY(tmpSocket->write("\r\n") > 0); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + QVERIFY(socket.write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); + QVERIFY(socket.write("HOST: ") > 0); + QVERIFY(socket.write(hostName.data()) > 0); + QVERIFY(socket.write("\r\n") > 0); + QVERIFY(socket.write("\r\n") > 0); + - bytesAvailable = 0; QTime stopWatch; stopWatch.start(); @@ -791,31 +774,12 @@ void tst_QSocks5SocketEngine::downloadBigFile() QCOMPARE(bytesAvailable, qint64(10000000)); - QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); /*qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s", bytesAvailable / (1024.0 * 1024.0), stopWatch.elapsed() / 1024.0, (bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));*/ - - delete tmpSocket; - tmpSocket = 0; -} - -void tst_QSocks5SocketEngine::exitLoopSlot() -{ - QTestEventLoop::instance().exitLoop(); -} - - -void tst_QSocks5SocketEngine::downloadBigFileSlot() -{ - QByteArray tmp=tmpSocket->readAll(); - int correction=tmp.indexOf((char)0,0); //skip header - if (correction==-1) correction=0; - bytesAvailable += (tmp.size()-correction); - if (bytesAvailable >= 10000000) - QTestEventLoop::instance().exitLoop(); } void tst_QSocks5SocketEngine::passwordAuth() -- cgit v1.2.3