From 707666963551ebcd1af5c06ad775fa99d1a0a9af Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Mon, 3 Jun 2024 01:11:48 +0200 Subject: [PATCH 1/5] Add very basic HTTP and HTTPS network tests. This seems to reproduce the problem I'm having with the Conan PR --- tests/networking/src/QtNetworkTests.cpp | 60 +++++++++++++++++++++++++ tests/networking/src/QtNetworkTests.h | 27 +++++++++++ 2 files changed, 87 insertions(+) create mode 100644 tests/networking/src/QtNetworkTests.cpp create mode 100644 tests/networking/src/QtNetworkTests.h diff --git a/tests/networking/src/QtNetworkTests.cpp b/tests/networking/src/QtNetworkTests.cpp new file mode 100644 index 00000000000..4d5b3ba7801 --- /dev/null +++ b/tests/networking/src/QtNetworkTests.cpp @@ -0,0 +1,60 @@ +// +// PacketTests.cpp +// tests/networking/src +// +// Created by Stephen Birarda on 07/14/15. +// Copyright 2015 High Fidelity, Inc. +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "QtNetworkTests.h" +#include + +#include +#include +#include +#include + + + +QTEST_MAIN(QtNetworkTests); + +void QtNetworkTests::initTestCase() { + qDebug() << "Init"; + qRegisterMetaType(); + +} +void QtNetworkTests::httpRequest() { + auto manager = new QNetworkAccessManager(); + + QSignalSpy spy(manager, &QNetworkAccessManager::finished); + QNetworkRequest req(QUrl("http://google.com")); + manager->get(req); + + spy.wait(); + + QCOMPARE(spy.count(), 1); + QList arguments = spy.takeFirst(); + QNetworkReply *reply = arguments.at(0).value(); + QVERIFY(!reply->error()); + qDebug() << reply->readAll().length() << "Bytes received"; +} + +void QtNetworkTests::httpsRequest() { +auto manager = new QNetworkAccessManager(); + + QSignalSpy spy(manager, &QNetworkAccessManager::finished); + QNetworkRequest req(QUrl("https://google.com")); + manager->get(req); + + spy.wait(); + + QCOMPARE(spy.count(), 1); + QList arguments = spy.takeFirst(); + QNetworkReply *reply = arguments.at(0).value(); + QVERIFY(!reply->error()); + qDebug() << reply->readAll().length() << "Bytes received"; +} diff --git a/tests/networking/src/QtNetworkTests.h b/tests/networking/src/QtNetworkTests.h new file mode 100644 index 00000000000..095f553f637 --- /dev/null +++ b/tests/networking/src/QtNetworkTests.h @@ -0,0 +1,27 @@ +// +// PacketTests.h +// tests/networking/src +// +// Created by Stephen Birarda on 07/14/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef overte_QtNetworkTests_h +#define overte_QtNetworkTests_h + +#pragma once + +#include + +class QtNetworkTests : public QObject { + Q_OBJECT +private slots: + void initTestCase(); + void httpRequest(); + void httpsRequest(); +}; + +#endif // overte_QtNetworkTests_h From 62cd9c64c1d7bbf55d94e792faacc91fe10c0e8e Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Mon, 3 Jun 2024 01:13:47 +0200 Subject: [PATCH 2/5] Fix indentation --- tests/networking/src/QtNetworkTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/networking/src/QtNetworkTests.cpp b/tests/networking/src/QtNetworkTests.cpp index 4d5b3ba7801..a4e36e7c660 100644 --- a/tests/networking/src/QtNetworkTests.cpp +++ b/tests/networking/src/QtNetworkTests.cpp @@ -44,7 +44,7 @@ void QtNetworkTests::httpRequest() { } void QtNetworkTests::httpsRequest() { -auto manager = new QNetworkAccessManager(); + auto manager = new QNetworkAccessManager(); QSignalSpy spy(manager, &QNetworkAccessManager::finished); QNetworkRequest req(QUrl("https://google.com")); From 57fcc378bf83b217b0b7c828fd2b5840b616efe4 Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Mon, 3 Jun 2024 20:55:38 +0200 Subject: [PATCH 3/5] Expand the test --- tests/networking/src/QtNetworkTests.cpp | 78 ++++++++++++++++++++++--- tests/networking/src/QtNetworkTests.h | 9 ++- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/tests/networking/src/QtNetworkTests.cpp b/tests/networking/src/QtNetworkTests.cpp index a4e36e7c660..bb70652e72c 100644 --- a/tests/networking/src/QtNetworkTests.cpp +++ b/tests/networking/src/QtNetworkTests.cpp @@ -2,9 +2,8 @@ // PacketTests.cpp // tests/networking/src // -// Created by Stephen Birarda on 07/14/15. -// Copyright 2015 High Fidelity, Inc. -// Copyright 2021 Vircadia contributors. +// Created by Dale Glass on 02/06/2024 +// Copyright 2024 Overte e.V. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -17,6 +16,25 @@ #include #include #include +#include +#include +#include +#include + +/** + * @brief Test basic Qt networking functionality + * + * This test was created to test a problem found with the Conan PR. + * Possibly some sort of library trouble. + * + * Normally there's no reason why this should go wrong, so it's mostly + * a test of that Qt is deployed and working properly. + * + */ +const QUrl HTTP_URL("http://ping.archlinux.org/"); +const QUrl HTTPS_URL("https://ping.archlinux.org/"); +const QString TCP_HOST("ping.archlinux.org"); +const QString SSL_HOST("ping.archlinux.org"); @@ -27,11 +45,50 @@ void QtNetworkTests::initTestCase() { qRegisterMetaType(); } + +void QtNetworkTests::tcpSocket() { + QTcpSocket sock; + QSignalSpy spy(&sock, &QTcpSocket::connected); + + qDebug() << "Connecting to" << TCP_HOST << "on port 80"; + sock.connectToHost(TCP_HOST, 80); + spy.wait(); + QVERIFY(sock.waitForConnected()); + QVERIFY(sock.localPort() > 0); + + qDebug() << "Local address is" << sock.localAddress() << ":" << sock.localPort(); +} + +void QtNetworkTests::sslSocket() { + QSslSocket sock; + QSignalSpy spy(&sock, &QSslSocket::connected); + + QVERIFY(QSslSocket::supportsSsl()); + qDebug() << "SSL library version: " << QSslSocket::sslLibraryVersionString(); + + qDebug() << "Connecting to" << SSL_HOST << "on port 443"; + sock.connectToHostEncrypted(SSL_HOST, 443); + spy.wait(); + QVERIFY(sock.waitForEncrypted()); + QVERIFY(sock.localPort() > 0); + + QVERIFY(!sock.sslConfiguration().isNull()); + QVERIFY(sock.sslHandshakeErrors().length() == 0); + QVERIFY(sock.sessionProtocol() != QSsl::UnknownProtocol); + + qDebug() << "Local address is" << sock.localAddress() << ":" << sock.localPort(); + qDebug() << "SSL protocol : " << sock.sessionProtocol(); + qDebug() << "SSL cipher : " << sock.sessionCipher().protocolString(); + qDebug() << "SSL cert : " << sock.peerCertificate(); +} + + void QtNetworkTests::httpRequest() { auto manager = new QNetworkAccessManager(); + qDebug() << "Making request to" << HTTP_URL; QSignalSpy spy(manager, &QNetworkAccessManager::finished); - QNetworkRequest req(QUrl("http://google.com")); + QNetworkRequest req(HTTP_URL); manager->get(req); spy.wait(); @@ -40,14 +97,18 @@ void QtNetworkTests::httpRequest() { QList arguments = spy.takeFirst(); QNetworkReply *reply = arguments.at(0).value(); QVERIFY(!reply->error()); - qDebug() << reply->readAll().length() << "Bytes received"; + QVERIFY(!reply->sslConfiguration().isNull()); + + QString data = reply->readAll(); + qDebug() << "DATA: " << data; } void QtNetworkTests::httpsRequest() { auto manager = new QNetworkAccessManager(); + qDebug() << "Making request to" << HTTPS_URL; QSignalSpy spy(manager, &QNetworkAccessManager::finished); - QNetworkRequest req(QUrl("https://google.com")); + QNetworkRequest req(HTTPS_URL); manager->get(req); spy.wait(); @@ -56,5 +117,8 @@ void QtNetworkTests::httpsRequest() { QList arguments = spy.takeFirst(); QNetworkReply *reply = arguments.at(0).value(); QVERIFY(!reply->error()); - qDebug() << reply->readAll().length() << "Bytes received"; + QVERIFY(!reply->sslConfiguration().isNull()); + + QString data = reply->readAll(); + qDebug() << "DATA: " << data; } diff --git a/tests/networking/src/QtNetworkTests.h b/tests/networking/src/QtNetworkTests.h index 095f553f637..a0c3a1b0380 100644 --- a/tests/networking/src/QtNetworkTests.h +++ b/tests/networking/src/QtNetworkTests.h @@ -1,14 +1,15 @@ // -// PacketTests.h +// PacketTests.cpp // tests/networking/src // -// Created by Stephen Birarda on 07/14/15. -// Copyright 2015 High Fidelity, Inc. +// Created by Dale Glass on 02/06/2024 +// Copyright 2024 Overte e.V. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + #ifndef overte_QtNetworkTests_h #define overte_QtNetworkTests_h @@ -20,6 +21,8 @@ class QtNetworkTests : public QObject { Q_OBJECT private slots: void initTestCase(); + void tcpSocket(); + void sslSocket(); void httpRequest(); void httpsRequest(); }; From aaf08cf52365bc6fd71f12fa3391da45057769b2 Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Mon, 3 Jun 2024 23:10:17 +0200 Subject: [PATCH 4/5] Add another SSL test. One gets the SSL version string. That initializes something in the guts of Qt, and gets things unstuck. Another doesn't and gets stuck if called as the only test. --- tests/networking/src/QtNetworkTests.cpp | 30 +++++++++++++++++++++++++ tests/networking/src/QtNetworkTests.h | 1 + 2 files changed, 31 insertions(+) diff --git a/tests/networking/src/QtNetworkTests.cpp b/tests/networking/src/QtNetworkTests.cpp index bb70652e72c..2e8ac1cd030 100644 --- a/tests/networking/src/QtNetworkTests.cpp +++ b/tests/networking/src/QtNetworkTests.cpp @@ -106,6 +106,11 @@ void QtNetworkTests::httpRequest() { void QtNetworkTests::httpsRequest() { auto manager = new QNetworkAccessManager(); + qDebug() << "SSL library version : " << QSslSocket::sslLibraryVersionString(); + qDebug() << "SSL library version : " << QSslSocket::sslLibraryVersionString(); + qDebug() << "SSL library build version: " << QSslSocket::sslLibraryBuildVersionString(); + + qDebug() << "Making request to" << HTTPS_URL; QSignalSpy spy(manager, &QNetworkAccessManager::finished); QNetworkRequest req(HTTPS_URL); @@ -118,7 +123,32 @@ void QtNetworkTests::httpsRequest() { QNetworkReply *reply = arguments.at(0).value(); QVERIFY(!reply->error()); QVERIFY(!reply->sslConfiguration().isNull()); + qDebug() << "Peer cert:" << reply->sslConfiguration().peerCertificate(); + QString data = reply->readAll(); + qDebug() << "DATA: " << data; + qDebug() << "SSL library version: " << QSslSocket::sslLibraryVersionString(); + +} + + +void QtNetworkTests::httpsRequestNoSSLVersion() { + auto manager = new QNetworkAccessManager(); + + qDebug() << "Making request to" << HTTPS_URL; + QSignalSpy spy(manager, &QNetworkAccessManager::finished); + QNetworkRequest req(HTTPS_URL); + manager->get(req); + spy.wait(); + + QCOMPARE(spy.count(), 1); + QList arguments = spy.takeFirst(); + QNetworkReply *reply = arguments.at(0).value(); + QVERIFY(!reply->error()); + QVERIFY(!reply->sslConfiguration().isNull()); + qDebug() << "Peer cert:" << reply->sslConfiguration().peerCertificate(); QString data = reply->readAll(); qDebug() << "DATA: " << data; + qDebug() << "SSL library version: " << QSslSocket::sslLibraryVersionString(); + } diff --git a/tests/networking/src/QtNetworkTests.h b/tests/networking/src/QtNetworkTests.h index a0c3a1b0380..1744598570b 100644 --- a/tests/networking/src/QtNetworkTests.h +++ b/tests/networking/src/QtNetworkTests.h @@ -24,6 +24,7 @@ private slots: void tcpSocket(); void sslSocket(); void httpRequest(); + void httpsRequestNoSSLVersion(); void httpsRequest(); }; From 338256f23416d0c3c3df30c0695b8e19bbc10096 Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Mon, 3 Jun 2024 23:14:11 +0200 Subject: [PATCH 5/5] Further explanatory comments --- tests/networking/src/QtNetworkTests.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/networking/src/QtNetworkTests.cpp b/tests/networking/src/QtNetworkTests.cpp index 2e8ac1cd030..e266ff216ca 100644 --- a/tests/networking/src/QtNetworkTests.cpp +++ b/tests/networking/src/QtNetworkTests.cpp @@ -30,6 +30,13 @@ * Normally there's no reason why this should go wrong, so it's mostly * a test of that Qt is deployed and working properly. * + * Turns out it's some sort of initialization issue. It can be reproduced by calling the test as: + * ./networking-QtNetworkTests httpsRequestNoSSLVersion + * + * This test may get stuck on some systems. Running the full suite, or: + * ./networking-QtNetworkTests httpsRequestNoSSLVersion + * + * will work correctly because QSslSocket::sslLibraryVersionString() initializes something. */ const QUrl HTTP_URL("http://ping.archlinux.org/"); const QUrl HTTPS_URL("https://ping.archlinux.org/"); @@ -103,6 +110,10 @@ void QtNetworkTests::httpRequest() { qDebug() << "DATA: " << data; } + +// Unlike the test below this works, because the sslLibraryVersionString call pokes something +// in the Qt guts to make things initialize properly. + void QtNetworkTests::httpsRequest() { auto manager = new QNetworkAccessManager(); @@ -131,6 +142,8 @@ void QtNetworkTests::httpsRequest() { } +// On some systems, this hangs forever. Something in the Qt guts fails to initialize. + void QtNetworkTests::httpsRequestNoSSLVersion() { auto manager = new QNetworkAccessManager();