diff options
Diffstat (limited to 'tests/auto/network/kernel')
27 files changed, 958 insertions, 861 deletions
diff --git a/tests/auto/network/kernel/CMakeLists.txt b/tests/auto/network/kernel/CMakeLists.txt index c7b0d0dfeb..b42a9724b3 100644 --- a/tests/auto/network/kernel/CMakeLists.txt +++ b/tests/auto/network/kernel/CMakeLists.txt @@ -1,11 +1,15 @@ -# Generated from kernel.pro. -if(NOT INTEGRITY) +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(QT_FEATURE_dnslookup AND (QT_FEATURE_libresolv OR WIN32)) add_subdirectory(qdnslookup) add_subdirectory(qdnslookup_appless) endif() -add_subdirectory(qnetworkproxyfactory) +if(QT_FEATURE_networkinterface) + add_subdirectory(qnetworkproxyfactory) + add_subdirectory(qnetworkinterface) +endif() add_subdirectory(qnetworkproxy) -add_subdirectory(qnetworkinterface) add_subdirectory(qnetworkdatagram) add_subdirectory(qnetworkaddressentry) add_subdirectory(qhostaddress) diff --git a/tests/auto/network/kernel/qauthenticator/CMakeLists.txt b/tests/auto/network/kernel/qauthenticator/CMakeLists.txt index d772fe0e28..552e9065ed 100644 --- a/tests/auto/network/kernel/qauthenticator/CMakeLists.txt +++ b/tests/auto/network/kernel/qauthenticator/CMakeLists.txt @@ -1,4 +1,11 @@ -# Generated from qauthenticator.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qauthenticator LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() if(NOT QT_FEATURE_private_tests) return() @@ -11,9 +18,6 @@ endif() qt_internal_add_test(tst_qauthenticator SOURCES tst_qauthenticator.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::NetworkPrivate ) - -#### Keys ignored in scope 1:.:.:qauthenticator.pro:<TRUE>: -# _REQUIREMENTS = "qtConfig(private_tests)" diff --git a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp index 529386f50f..1cd1b6a63b 100644 --- a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp +++ b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp @@ -1,36 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the FOO module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/QString> #include <QTest> #include <QtCore/QCoreApplication> #include <QtNetwork/QAuthenticator> +#include <QtNetwork/QHttpHeaders> #include <private/qauthenticator_p.h> @@ -48,6 +24,8 @@ private Q_SLOTS: void ntlmAuth_data(); void ntlmAuth(); + void sha256AndMd5Digest(); + void equalityOperators(); void isMethodSupported(); @@ -83,8 +61,8 @@ void tst_QAuthenticator::basicAuth() QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth); QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); - QList<QPair<QByteArray, QByteArray> > headers; - headers << qMakePair(QByteArray("WWW-Authenticate"), "Basic " + data.toUtf8()); + QHttpHeaders headers; + headers.append(QByteArray("WWW-Authenticate"), "Basic " + data.toUtf8()); priv->parseHttpResponse(headers, /*isProxy = */ false, {}); QCOMPARE(auth.realm(), realm); @@ -95,7 +73,7 @@ void tst_QAuthenticator::basicAuth() QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); - QCOMPARE(priv->calculateResponse("GET", "/", "").constData(), QByteArray("Basic " + expectedReply).constData()); + QCOMPARE(priv->calculateResponse("GET", "/", u"").constData(), QByteArray("Basic " + expectedReply).constData()); } void tst_QAuthenticator::ntlmAuth_data() @@ -126,29 +104,58 @@ void tst_QAuthenticator::ntlmAuth() QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth); QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); - QList<QPair<QByteArray, QByteArray> > headers; + QHttpHeaders headers; // NTLM phase 1: negotiate // This phase of NTLM contains no information, other than what we're willing to negotiate // Current implementation uses flags: // NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET - headers << qMakePair(QByteArrayLiteral("WWW-Authenticate"), QByteArrayLiteral("NTLM")); + headers.append(QByteArrayLiteral("WWW-Authenticate"), QByteArrayLiteral("NTLM")); priv->parseHttpResponse(headers, /*isProxy = */ false, {}); if (sso) - QVERIFY(priv->calculateResponse("GET", "/", "").startsWith("NTLM ")); + QVERIFY(priv->calculateResponse("GET", "/", u"").startsWith("NTLM ")); else - QCOMPARE(priv->calculateResponse("GET", "/", "").constData(), "NTLM TlRMTVNTUAABAAAABYIIAAAAAAAAAAAAAAAAAAAAAAA="); + QCOMPARE(priv->calculateResponse("GET", "/", u"").constData(), "NTLM TlRMTVNTUAABAAAABYIIAAAAAAAAAAAAAAAAAAAAAAA="); // NTLM phase 2: challenge headers.clear(); - headers << qMakePair(QByteArray("WWW-Authenticate"), "NTLM " + data.toUtf8()); + headers.append(QByteArray("WWW-Authenticate"), "NTLM " + data.toUtf8()); priv->parseHttpResponse(headers, /*isProxy = */ false, {}); QEXPECT_FAIL("with-realm", "NTLM authentication code doesn't extract the realm", Continue); QEXPECT_FAIL("with-realm-sso", "NTLM authentication code doesn't extract the realm", Continue); QCOMPARE(auth.realm(), realm); - QVERIFY(priv->calculateResponse("GET", "/", "").startsWith("NTLM ")); + QVERIFY(priv->calculateResponse("GET", "/", u"").startsWith("NTLM ")); +} + +// We don't (currently) support SHA256. So, when presented with the option of MD5 or SHA256, +// we should always pick MD5. +void tst_QAuthenticator::sha256AndMd5Digest() +{ + QByteArray md5 = "Digest realm=\"\", nonce=\"\", algorithm=MD5, qop=\"auth\""; + QByteArray sha256 = "Digest realm=\"\", nonce=\"\", algorithm=SHA-256, qop=\"auth\""; + + QAuthenticator auth; + auth.setUser("unimportant"); + auth.setPassword("unimportant"); + + QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth); + QVERIFY(priv->isMethodSupported("digest")); // sanity check + + QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); + QHttpHeaders headers; + // Put sha256 first, so that its parsed first... + headers.append("WWW-Authenticate", sha256); + headers.append("WWW-Authenticate", md5); + priv->parseHttpResponse(headers, false, QString()); + + QByteArray response = priv->calculateResponse("GET", "/index", {}); + QCOMPARE(priv->phase, QAuthenticatorPrivate::Done); + + QVERIFY(!response.isEmpty()); + QVERIFY(!response.contains("algorithm=SHA-256")); + QVERIFY(response.contains("algorithm=MD5")); } void tst_QAuthenticator::equalityOperators() diff --git a/tests/auto/network/kernel/qdnslookup/BLACKLIST b/tests/auto/network/kernel/qdnslookup/BLACKLIST deleted file mode 100644 index f07a8ce9a3..0000000000 --- a/tests/auto/network/kernel/qdnslookup/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[lookup] -* diff --git a/tests/auto/network/kernel/qdnslookup/CMakeLists.txt b/tests/auto/network/kernel/qdnslookup/CMakeLists.txt index b039b4e91b..ea539ecbe0 100644 --- a/tests/auto/network/kernel/qdnslookup/CMakeLists.txt +++ b/tests/auto/network/kernel/qdnslookup/CMakeLists.txt @@ -1,12 +1,25 @@ -# Generated from qdnslookup.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qdnslookup Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qdnslookup LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qdnslookup SOURCES tst_qdnslookup.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Network + Qt::TestPrivate +) + +qt_internal_extend_target(tst_qdnslookup CONDITION WIN32 + LIBRARIES + iphlpapi ) diff --git a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp index f462330fdf..f71e94862c 100644 --- a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp +++ b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp @@ -1,64 +1,186 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org> -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - +// Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org> +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QSignalSpy> +#include <QtTest/private/qpropertytesthelper_p.h> #include <QtNetwork/QDnsLookup> + +#include <QtCore/QRandomGenerator> #include <QtNetwork/QHostAddress> +#include <QtNetwork/QNetworkDatagram> +#include <QtNetwork/QUdpSocket> + +#ifdef Q_OS_UNIX +# include <QtCore/QFile> +#else +# include <winsock2.h> +# include <iphlpapi.h> +#endif +using namespace Qt::StringLiterals; static const int Timeout = 15000; // 15s class tst_QDnsLookup: public QObject { Q_OBJECT + const QString normalDomain = u".test.qt-project.org"_s; + const QString idnDomain = u".alqualondë.test.qt-project.org"_s; + bool usingIdnDomain = false; + bool dnsServersMustWork = false; + QString domainName(const QString &input); QString domainNameList(const QString &input); QStringList domainNameListAlternatives(const QString &input); + + std::unique_ptr<QDnsLookup> lookupCommon(QDnsLookup::Type type, const QString &domain, + const QHostAddress &server = {}, quint16 port = 53); + QStringList formatReply(const QDnsLookup *lookup) const; public slots: void initTestCase(); private slots: + void lookupLocalhost(); + void lookupRoot(); + void lookupNxDomain_data(); + void lookupNxDomain(); void lookup_data(); void lookup(); + void lookupIdn_data() { lookup_data(); } + void lookupIdn(); + void lookupReuse(); void lookupAbortRetry(); + void setNameserverLoopback(); + void setNameserver_data(); + void setNameserver(); void bindingsAndProperties(); + void automatedBindings(); }; +static constexpr qsizetype HeaderSize = 6 * sizeof(quint16); +static const char preparedDnsQuery[] = + // header + "\x00\x00" // transaction ID, we'll replace + "\x01\x20" // flags + "\x00\x01" // qdcount + "\x00\x00" // ancount + "\x00\x00" // nscount + "\x00\x00" // arcount + // query: + "\x00\x00\x06\x00\x01" // <root domain> IN SOA + ; + +static QList<QHostAddress> systemNameservers() +{ + QList<QHostAddress> result; + +#ifdef Q_OS_WIN + ULONG infosize = 0; + DWORD r = GetNetworkParams(nullptr, &infosize); + auto buffer = std::make_unique<uchar[]>(infosize); + auto info = new (buffer.get()) FIXED_INFO; + r = GetNetworkParams(info, &infosize); + if (r == NO_ERROR) { + for (PIP_ADDR_STRING ptr = &info->DnsServerList; ptr; ptr = ptr->Next) { + QLatin1StringView addr(ptr->IpAddress.String); + result.emplaceBack(addr); + } + } +#else + auto parseFile = [&](QLatin1StringView path) { + QFile f(path); + if (!f.open(QIODevice::ReadOnly)) + return; + + while (!f.atEnd()) { + static const char command[] = "nameserver"; + QByteArray line = f.readLine().simplified(); + if (!line.startsWith(command)) + continue; + + QString addr = QLatin1StringView(line).mid(sizeof(command)); + result.emplaceBack(addr); + } + }; + parseFile("/etc/resolv.conf"_L1); + parseFile("/run/systemd/resolve/resolv.conf"_L1); +#endif + + return result; +} + +static QList<QHostAddress> globalPublicNameservers() +{ + const char *const candidates[] = { + // Google's dns.google + "8.8.8.8", "2001:4860:4860::8888", + //"8.8.4.4", "2001:4860:4860::8844", + + // CloudFare's one.one.one.one + "1.1.1.1", "2606:4700:4700::1111", + //"1.0.0.1", "2606:4700:4700::1001", + + // Quad9's dns9 + //"9.9.9.9", "2620:fe::9", + }; + + QList<QHostAddress> result; + QRandomGenerator &rng = *QRandomGenerator::system(); + for (auto name : candidates) { + // check the candidates for reachability + QHostAddress addr{QLatin1StringView(name)}; + quint16 id = quint16(rng()); + QByteArray data(preparedDnsQuery, sizeof(preparedDnsQuery)); + char *ptr = data.data(); + qToBigEndian(id, ptr); + + QUdpSocket socket; + socket.connectToHost(addr, 53); + if (socket.waitForConnected(1)) + socket.write(data); + + if (!socket.waitForReadyRead(1000)) { + qDebug() << addr << "discarded:" << socket.errorString(); + continue; + } + + QNetworkDatagram dgram = socket.receiveDatagram(); + if (!dgram.isValid()) { + qDebug() << addr << "discarded:" << socket.errorString(); + continue; + } + + data = dgram.data(); + ptr = data.data(); + if (data.size() < HeaderSize) { + qDebug() << addr << "discarded: reply too small"; + continue; + } + + bool ok = qFromBigEndian<quint16>(ptr) == id + && (ptr[2] & 0x80) // is a reply + && (ptr[3] & 0xf) == 0 // rcode NOERROR + && qFromBigEndian<quint16>(ptr + 4) == 1 // qdcount + && qFromBigEndian<quint16>(ptr + 6) >= 1; // ancount + if (!ok) { + qDebug() << addr << "discarded: invalid reply"; + continue; + } + + result.emplaceBack(std::move(addr)); + } + + return result; +} + void tst_QDnsLookup::initTestCase() { - QTest::addColumn<QString>("tld"); - QTest::newRow("normal") << ".test.qt-project.org"; - QTest::newRow("idn") << ".alqualond\xc3\xab.test.qt-project.org"; + if (qgetenv("QTEST_ENVIRONMENT") == "ci") + dnsServersMustWork = true; } QString tst_QDnsLookup::domainName(const QString &input) @@ -72,15 +194,16 @@ QString tst_QDnsLookup::domainName(const QString &input) return nodot; } - QFETCH_GLOBAL(QString, tld); - return input + tld; + if (usingIdnDomain) + return input + idnDomain; + return input + normalDomain; } QString tst_QDnsLookup::domainNameList(const QString &input) { - QStringList list = input.split(QLatin1Char(';')); + const QStringList list = input.split(QLatin1Char(';')); QString result; - foreach (const QString &s, list) { + for (const QString &s : list) { if (!result.isEmpty()) result += ';'; result += domainName(s); @@ -91,229 +214,272 @@ QString tst_QDnsLookup::domainNameList(const QString &input) QStringList tst_QDnsLookup::domainNameListAlternatives(const QString &input) { QStringList alternatives = input.split('|'); - for (int i = 0; i < alternatives.length(); ++i) + for (int i = 0; i < alternatives.size(); ++i) alternatives[i] = domainNameList(alternatives[i]); return alternatives; } +std::unique_ptr<QDnsLookup> +tst_QDnsLookup::lookupCommon(QDnsLookup::Type type, const QString &domain, + const QHostAddress &server, quint16 port) +{ + auto lookup = std::make_unique<QDnsLookup>(type, domainName(domain), server, port); + QObject::connect(lookup.get(), &QDnsLookup::finished, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + lookup->lookup(); + QTestEventLoop::instance().enterLoopMSecs(Timeout); + + QDnsLookup::Error error = lookup->error(); + if (QTestEventLoop::instance().timeout()) + error = QDnsLookup::TimeoutError; + + if (!dnsServersMustWork && (error == QDnsLookup::ServerFailureError + || error == QDnsLookup::ServerRefusedError + || error == QDnsLookup::TimeoutError)) { + // It's not a QDnsLookup problem if the server refuses to answer the query. + // This happens for queries of type ANY through Dnsmasq, for example. + [&] { + auto me = QMetaEnum::fromType<QDnsLookup::Type>(); + QString msg = u"Server refused or was unable to answer query; %1 type %3: %2"_s + .arg(domain, lookup->errorString(), QString(me.valueToKey(int(type)))); + QSKIP(msg.toLocal8Bit()); + }(); + return {}; + } + + return lookup; +} + +QStringList tst_QDnsLookup::formatReply(const QDnsLookup *lookup) const +{ + QStringList result; + QString domain = lookup->name(); + + auto shorter = [this](QString value) { + const QString &ending = usingIdnDomain ? idnDomain : normalDomain; + if (value.endsWith(ending)) + value.chop(ending.size()); + else + value += u'.'; + return value; + }; + + for (const QDnsMailExchangeRecord &rr : lookup->mailExchangeRecords()) { + QString entry = u"MX %1 %2"_s.arg(rr.preference(), 5).arg(shorter(rr.exchange())); + if (rr.name() != domain) + entry = "MX unexpected label to "_L1 + rr.name(); + result.append(std::move(entry)); + } + + for (const QDnsServiceRecord &rr : lookup->serviceRecords()) { + QString entry = u"SRV %1 %2 %3 %4"_s.arg(rr.priority(), 5).arg(rr.weight()) + .arg(rr.port()).arg(shorter(rr.target())); + if (rr.name() != domain) + entry = "SRV unexpected label to "_L1 + rr.name(); + result.append(std::move(entry)); + } + + auto addNameRecords = [&](QLatin1StringView rrtype, const QList<QDnsDomainNameRecord> &rrset) { + for (const QDnsDomainNameRecord &rr : rrset) { + QString entry = u"%1 %2"_s.arg(rrtype, shorter(rr.value())); + if (rr.name() != domain) + entry = rrtype + " unexpected label to "_L1 + rr.name(); + result.append(std::move(entry)); + } + }; + addNameRecords("NS"_L1, lookup->nameServerRecords()); + addNameRecords("PTR"_L1, lookup->pointerRecords()); + addNameRecords("CNAME"_L1, lookup->canonicalNameRecords()); + + for (const QDnsHostAddressRecord &rr : lookup->hostAddressRecords()) { + if (rr.name() != domain) + continue; // A and AAAA may appear as extra records in the answer section + QHostAddress addr = rr.value(); + result.append(u"%1 %2"_s + .arg(addr.protocol() == QHostAddress::IPv6Protocol ? "AAAA" : "A", + addr.toString())); + } + + for (const QDnsTextRecord &rr : lookup->textRecords()) { + QString entry = "TXT"_L1; + for (const QByteArray &data : rr.values()) { + entry += u' '; + entry += QDebug::toString(data); + } + result.append(std::move(entry)); + } + + result.sort(); + return result; +} + +void tst_QDnsLookup::lookupLocalhost() +{ + auto lookup = lookupCommon(QDnsLookup::Type::A, u"localhost."_s); + QVERIFY(lookup); + QCOMPARE(lookup->error(), QDnsLookup::NoError); + + QList<QDnsHostAddressRecord> hosts = lookup->hostAddressRecords(); + QCOMPARE(hosts.size(), 1); + QCOMPARE(hosts.at(0).value(), QHostAddress::LocalHost); + QVERIFY2(hosts.at(0).name().startsWith(lookup->name()), + qPrintable(hosts.at(0).name())); +} + +void tst_QDnsLookup::lookupRoot() +{ +#ifdef Q_OS_WIN + QSKIP("This test fails on Windows as it seems to treat the lookup as a local one."); +#else + auto lookup = lookupCommon(QDnsLookup::Type::NS, u""_s); + if (!lookup) + return; + QCOMPARE(lookup->error(), QDnsLookup::NoError); + + const QList<QDnsDomainNameRecord> servers = lookup->nameServerRecords(); + QVERIFY(!servers.isEmpty()); + for (const QDnsDomainNameRecord &ns : servers) { + QCOMPARE(ns.name(), QString()); + QVERIFY(ns.value().endsWith(".root-servers.net")); + } +#endif +} + +void tst_QDnsLookup::lookupNxDomain_data() +{ + QTest::addColumn<QDnsLookup::Type>("type"); + QTest::addColumn<QString>("domain"); + + QTest::newRow("a") << QDnsLookup::A << "invalid.invalid"; + QTest::newRow("aaaa") << QDnsLookup::AAAA << "invalid.invalid"; + QTest::newRow("any") << QDnsLookup::ANY << "invalid.invalid"; + QTest::newRow("mx") << QDnsLookup::MX << "invalid.invalid"; + QTest::newRow("ns") << QDnsLookup::NS << "invalid.invalid"; + QTest::newRow("ptr") << QDnsLookup::PTR << "invalid.invalid"; + QTest::newRow("srv") << QDnsLookup::SRV << "invalid.invalid"; + QTest::newRow("txt") << QDnsLookup::TXT << "invalid.invalid"; +} + +void tst_QDnsLookup::lookupNxDomain() +{ + QFETCH(QDnsLookup::Type, type); + QFETCH(QString, domain); + + auto lookup = lookupCommon(type, domain); + if (!lookup) + return; + QCOMPARE(lookup->name(), domainName(domain)); + QCOMPARE(lookup->type(), type); + QCOMPARE(lookup->error(), QDnsLookup::NotFoundError); +} + void tst_QDnsLookup::lookup_data() { - QTest::addColumn<int>("type"); + QTest::addColumn<QDnsLookup::Type>("type"); QTest::addColumn<QString>("domain"); - QTest::addColumn<int>("error"); - QTest::addColumn<QString>("cname"); - QTest::addColumn<QString>("host"); - QTest::addColumn<QString>("mx"); - QTest::addColumn<QString>("ns"); - QTest::addColumn<QString>("ptr"); - QTest::addColumn<QString>("srv"); - QTest::addColumn<QString>("txt"); - - QTest::newRow("a-empty") << int(QDnsLookup::A) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << ""<< "" << ""; - QTest::newRow("a-notfound") << int(QDnsLookup::A) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("a-single") << int(QDnsLookup::A) << "a-single" << int(QDnsLookup::NoError) << "" << "192.0.2.1" << "" << "" << "" << "" << ""; - QTest::newRow("a-multi") << int(QDnsLookup::A) << "a-multi" << int(QDnsLookup::NoError) << "" << "192.0.2.1;192.0.2.2;192.0.2.3" << "" << "" << "" << "" << ""; - QTest::newRow("aaaa-empty") << int(QDnsLookup::AAAA) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("aaaa-notfound") << int(QDnsLookup::AAAA) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("aaaa-single") << int(QDnsLookup::AAAA) << "aaaa-single" << int(QDnsLookup::NoError) << "" << "2001:db8::1" << "" << "" << "" << "" << ""; - QTest::newRow("aaaa-multi") << int(QDnsLookup::AAAA) << "aaaa-multi" << int(QDnsLookup::NoError) << "" << "2001:db8::1;2001:db8::2;2001:db8::3" << "" << "" << "" << "" << ""; - - QTest::newRow("any-empty") << int(QDnsLookup::ANY) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("any-notfound") << int(QDnsLookup::ANY) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("any-a-single") << int(QDnsLookup::ANY) << "a-single" << int(QDnsLookup::NoError) << "" << "192.0.2.1" << "" << "" << "" << "" << ""; - QTest::newRow("any-a-plus-aaaa") << int(QDnsLookup::ANY) << "a-plus-aaaa" << int(QDnsLookup::NoError) << "" << "198.51.100.1;2001:db8::1:1" << "" << "" << "" << "" << ""; - QTest::newRow("any-multi") << int(QDnsLookup::ANY) << "multi" << int(QDnsLookup::NoError) << "" << "198.51.100.1;198.51.100.2;198.51.100.3;2001:db8::1:1;2001:db8::1:2" << "" << "" << "" << "" << ""; - - QTest::newRow("mx-empty") << int(QDnsLookup::MX) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("mx-notfound") << int(QDnsLookup::MX) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("mx-single") << int(QDnsLookup::MX) << "mx-single" << int(QDnsLookup::NoError) << "" << "" << "10 multi" << "" << "" << "" << ""; - QTest::newRow("mx-single-cname") << int(QDnsLookup::MX) << "mx-single-cname" << int(QDnsLookup::NoError) << "" << "" << "10 cname" << "" << "" << "" << ""; - QTest::newRow("mx-multi") << int(QDnsLookup::MX) << "mx-multi" << int(QDnsLookup::NoError) << "" << "" << "10 multi;20 a-single" << "" << "" << "" << ""; - QTest::newRow("mx-multi-sameprio") << int(QDnsLookup::MX) << "mx-multi-sameprio" << int(QDnsLookup::NoError) << "" << "" - << "10 multi;10 a-single|" - "10 a-single;10 multi" << "" << "" << "" << ""; - - QTest::newRow("ns-empty") << int(QDnsLookup::NS) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("ns-notfound") << int(QDnsLookup::NS) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("ns-single") << int(QDnsLookup::NS) << "ns-single" << int(QDnsLookup::NoError) << "" << "" << "" << "ns11.cloudns.net." << "" << "" << ""; - QTest::newRow("ns-multi") << int(QDnsLookup::NS) << "ns-multi" << int(QDnsLookup::NoError) << "" << "" << "" << "ns11.cloudns.net.;ns12.cloudns.net." << "" << "" << ""; - - QTest::newRow("ptr-empty") << int(QDnsLookup::PTR) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("ptr-notfound") << int(QDnsLookup::PTR) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; + QTest::addColumn<QString>("expected"); + + QTest::newRow("a-single") << QDnsLookup::A << "a-single" + << "A 192.0.2.1"; + QTest::newRow("a-multi") << QDnsLookup::A << "a-multi" + << "A 192.0.2.1;A 192.0.2.2;A 192.0.2.3"; + QTest::newRow("aaaa-single") << QDnsLookup::AAAA << "aaaa-single" + << "AAAA 2001:db8::1"; + QTest::newRow("aaaa-multi") << QDnsLookup::AAAA << "aaaa-multi" + << "AAAA 2001:db8::1;AAAA 2001:db8::2;AAAA 2001:db8::3"; + + QTest::newRow("any-a-single") << QDnsLookup::ANY << "a-single" + << "A 192.0.2.1"; + QTest::newRow("any-a-plus-aaaa") << QDnsLookup::ANY << "a-plus-aaaa" + << "A 198.51.100.1;AAAA 2001:db8::1:1"; + QTest::newRow("any-multi") << QDnsLookup::ANY << "multi" + << "A 198.51.100.1;A 198.51.100.2;A 198.51.100.3;" + "AAAA 2001:db8::1:1;AAAA 2001:db8::1:2" ; + + QTest::newRow("mx-single") << QDnsLookup::MX << "mx-single" + << "MX 10 multi"; + QTest::newRow("mx-single-cname") << QDnsLookup::MX << "mx-single-cname" + << "MX 10 cname"; + QTest::newRow("mx-multi") << QDnsLookup::MX << "mx-multi" + << "MX 10 multi;MX 20 a-single"; + QTest::newRow("mx-multi-sameprio") << QDnsLookup::MX << "mx-multi-sameprio" + << "MX 10 a-single;MX 10 multi"; + + QTest::newRow("ns-single") << QDnsLookup::NS << "ns-single" + << "NS ns11.cloudns.net."; + QTest::newRow("ns-multi") << QDnsLookup::NS << "ns-multi" + << "NS ns11.cloudns.net.;NS ns12.cloudns.net."; + #if 0 // temporarily disabled since the new hosting provider can't insert // PTR records outside of the in-addr.arpa zone - QTest::newRow("ptr-single") << int(QDnsLookup::PTR) << "ptr-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "a-single" << "" << ""; + QTest::newRow("ptr-single") << QDnsLookup::PTR << "ptr-single" + << "PTR a-single"; #endif - - QTest::newRow("srv-empty") << int(QDnsLookup::SRV) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("srv-notfound") << int(QDnsLookup::SRV) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("srv-single") << int(QDnsLookup::SRV) << "_echo._tcp.srv-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "5 0 7 multi" << ""; - QTest::newRow("srv-prio") << int(QDnsLookup::SRV) << "_echo._tcp.srv-prio" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "1 0 7 multi;2 0 7 a-plus-aaaa" << ""; - QTest::newRow("srv-weighted") << int(QDnsLookup::SRV) << "_echo._tcp.srv-weighted" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" - << "5 75 7 multi;5 25 7 a-plus-aaaa|" - "5 25 7 a-plus-aaaa;5 75 7 multi" << ""; - QTest::newRow("srv-multi") << int(QDnsLookup::SRV) << "_echo._tcp.srv-multi" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" - << "1 50 7 multi;2 50 7 a-single;2 50 7 aaaa-single;3 50 7 a-multi|" - "1 50 7 multi;2 50 7 aaaa-single;2 50 7 a-single;3 50 7 a-multi" << ""; - - QTest::newRow("txt-empty") << int(QDnsLookup::TXT) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("txt-notfound") << int(QDnsLookup::TXT) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << ""; - QTest::newRow("txt-single") << int(QDnsLookup::TXT) << "txt-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" << "Hello"; - QTest::newRow("txt-multi-onerr") << int(QDnsLookup::TXT) << "txt-multi-onerr" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" - << QString::fromLatin1("Hello\0World", sizeof("Hello\0World") - 1); - QTest::newRow("txt-multi-multirr") << int(QDnsLookup::TXT) << "txt-multi-multirr" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" << "Hello;World"; -} - -static QByteArray msgDnsLookup(QDnsLookup::Error actualError, - int expectedError, - const QString &domain, - const QString &cname, - const QString &host, - const QString &srv, - const QString &mx, - const QString &ns, - const QString &ptr, - const QString &errorString) -{ - QString result; - QTextStream str(&result); - str << "Actual error: " << actualError; - if (!errorString.isEmpty()) - str << " (" << errorString << ')'; - str << ", expected: " << expectedError; - str << ", domain: " << domain; - if (!cname.isEmpty()) - str << ", cname: " << cname; - str << ", host: " << host; - if (!srv.isEmpty()) - str << " server: " << srv; - if (!mx.isEmpty()) - str << " mx: " << mx; - if (!ns.isEmpty()) - str << " ns: " << ns; - if (!ptr.isEmpty()) - str << " ptr: " << ptr; - return result.toLocal8Bit(); + QTest::newRow("ptr-1.1.1.1") << QDnsLookup::PTR << "1.1.1.1.in-addr.arpa." + << "PTR one.one.one.one."; + QTest::newRow("ptr-8.8.8.8") << QDnsLookup::PTR << "8.8.8.8.in-addr.arpa." + << "PTR dns.google."; + QTest::newRow("ptr-2001:4860:4860::8888") + << QDnsLookup::PTR << "8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa." + << "PTR dns.google."; + QTest::newRow("ptr-2606:4700:4700::1111") + << QDnsLookup::PTR << "1.1.1.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.4.0.0.7.4.6.0.6.2.ip6.arpa." + << "PTR one.one.one.one."; + + QTest::newRow("srv-single") << QDnsLookup::SRV << "_echo._tcp.srv-single" + << "SRV 5 0 7 multi"; + QTest::newRow("srv-prio") << QDnsLookup::SRV << "_echo._tcp.srv-prio" + << "SRV 1 0 7 multi;SRV 2 0 7 a-plus-aaaa"; + QTest::newRow("srv-weighted") << QDnsLookup::SRV << "_echo._tcp.srv-weighted" + << "SRV 5 25 7 a-plus-aaaa;SRV 5 75 7 multi"; + QTest::newRow("srv-multi") << QDnsLookup::SRV << "_echo._tcp.srv-multi" + << "SRV 1 50 7 multi;" + "SRV 2 50 7 a-single;" + "SRV 2 50 7 aaaa-single;" + "SRV 3 50 7 a-multi"; + + QTest::newRow("txt-single") << QDnsLookup::TXT << "txt-single" + << "TXT \"Hello\""; + QTest::newRow("txt-multi-onerr") << QDnsLookup::TXT << "txt-multi-onerr" + << "TXT \"Hello\" \"World\""; + QTest::newRow("txt-multi-multirr") << QDnsLookup::TXT << "txt-multi-multirr" + << "TXT \"Hello\";TXT \"World\""; } void tst_QDnsLookup::lookup() { - QFETCH(int, type); + QFETCH(QDnsLookup::Type, type); QFETCH(QString, domain); - QFETCH(int, error); - QFETCH(QString, cname); - QFETCH(QString, host); - QFETCH(QString, mx); - QFETCH(QString, ns); - QFETCH(QString, ptr); - QFETCH(QString, srv); - QFETCH(QString, txt); - - // transform the inputs - domain = domainName(domain); - cname = domainName(cname); - ns = domainNameList(ns); - ptr = domainNameList(ptr); - - // SRV and MX have reply entries that can change order - // and we can't sort - QStringList mx_alternatives = domainNameListAlternatives(mx); - QStringList srv_alternatives = domainNameListAlternatives(srv); + QFETCH(QString, expected); - QDnsLookup lookup; - lookup.setType(static_cast<QDnsLookup::Type>(type)); - lookup.setName(domain); - lookup.lookup(); - QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); + std::unique_ptr<QDnsLookup> lookup = lookupCommon(type, domain); + if (!lookup) + return; -#if defined(Q_OS_ANDROID) - if (lookup.errorString() == QStringLiteral("Not yet supported on Android")) - QEXPECT_FAIL("", "Not yet supported on Android", Abort); -#endif + QCOMPARE(lookup->error(), QDnsLookup::NoError); + QCOMPARE(lookup->errorString(), QString()); + QCOMPARE(lookup->type(), type); + QCOMPARE(lookup->name(), domainName(domain)); - QVERIFY2(int(lookup.error()) == error, - msgDnsLookup(lookup.error(), error, domain, cname, host, srv, mx, ns, ptr, lookup.errorString())); - if (error == QDnsLookup::NoError) - QVERIFY(lookup.errorString().isEmpty()); - QCOMPARE(int(lookup.type()), type); - QCOMPARE(lookup.name(), domain); - - // canonical names - if (!cname.isEmpty()) { - QVERIFY(!lookup.canonicalNameRecords().isEmpty()); - const QDnsDomainNameRecord cnameRecord = lookup.canonicalNameRecords().first(); - QCOMPARE(cnameRecord.name(), domain); - QCOMPARE(cnameRecord.value(), cname); - } else { - QVERIFY(lookup.canonicalNameRecords().isEmpty()); - } + QString result = formatReply(lookup.get()).join(u';'); + QCOMPARE(result, expected); - // host addresses - const QString hostName = cname.isEmpty() ? domain : cname; - QStringList addresses; - foreach (const QDnsHostAddressRecord &record, lookup.hostAddressRecords()) { - //reply may include A & AAAA records for nameservers, ignore them and only look at records matching the query - if (record.name() == hostName) - addresses << record.value().toString().toLower(); - } - addresses.sort(); - QCOMPARE(addresses.join(';'), host); - - // mail exchanges - QStringList mailExchanges; - foreach (const QDnsMailExchangeRecord &record, lookup.mailExchangeRecords()) { - QCOMPARE(record.name(), domain); - mailExchanges << QString::number(record.preference()) + QLatin1Char(' ') + record.exchange(); - } - QVERIFY2(mx_alternatives.contains(mailExchanges.join(';')), - qPrintable("Actual: " + mailExchanges.join(';') + "\nExpected one of:\n" + mx_alternatives.join('\n'))); - - // name servers - QStringList nameServers; - foreach (const QDnsDomainNameRecord &record, lookup.nameServerRecords()) { - //reply may include NS records for authoritative nameservers, ignore them and only look at records matching the query - if (record.name() == domain) - nameServers << record.value(); - } - nameServers.sort(); - QCOMPARE(nameServers.join(';'), ns); - - // pointers - if (!ptr.isEmpty()) { - QVERIFY(!lookup.pointerRecords().isEmpty()); - const QDnsDomainNameRecord ptrRecord = lookup.pointerRecords().first(); - QCOMPARE(ptrRecord.name(), domain); - QCOMPARE(ptrRecord.value(), ptr); - } else { - QVERIFY(lookup.pointerRecords().isEmpty()); - } + // confirm that MX and SRV records are properly sorted + const QList<QDnsMailExchangeRecord> mx = lookup->mailExchangeRecords(); + for (qsizetype i = 1; i < mx.size(); ++i) + QCOMPARE_GE(mx[i].preference(), mx[i - 1].preference()); - // services - QStringList services; - foreach (const QDnsServiceRecord &record, lookup.serviceRecords()) { - QCOMPARE(record.name(), domain); - services << (QString::number(record.priority()) + QLatin1Char(' ') - + QString::number(record.weight()) + QLatin1Char(' ') - + QString::number(record.port()) + QLatin1Char(' ') + record.target()); - } - QVERIFY2(srv_alternatives.contains(services.join(';')), - qPrintable("Actual: " + services.join(';') + "\nExpected one of:\n" + srv_alternatives.join('\n'))); - - // text - QStringList texts; - foreach (const QDnsTextRecord &record, lookup.textRecords()) { - QCOMPARE(record.name(), domain); - QString text; - foreach (const QByteArray &ba, record.values()) { - if (!text.isEmpty()) - text += '\0'; - text += QString::fromLatin1(ba); - } - texts << text; - } - texts.sort(); - QCOMPARE(texts.join(';'), txt); + const QList<QDnsServiceRecord> srv = lookup->serviceRecords(); + for (qsizetype i = 1; i < srv.size(); ++i) + QCOMPARE_GE(srv[i].priority(), srv[i - 1].priority()); +} + +void tst_QDnsLookup::lookupIdn() +{ + usingIdnDomain = true; + lookup(); + usingIdnDomain = false; } void tst_QDnsLookup::lookupReuse() @@ -326,11 +492,6 @@ void tst_QDnsLookup::lookupReuse() lookup.lookup(); QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); -#if defined(Q_OS_ANDROID) - if (lookup.errorString() == QStringLiteral("Not yet supported on Android")) - QEXPECT_FAIL("", "Not yet supported on Android", Abort); -#endif - QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError)); QVERIFY(!lookup.hostAddressRecords().isEmpty()); QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("a-single")); @@ -367,23 +528,96 @@ void tst_QDnsLookup::lookupAbortRetry() lookup.lookup(); QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); -#if defined(Q_OS_ANDROID) - if (lookup.errorString() == QStringLiteral("Not yet supported on Android")) - QEXPECT_FAIL("", "Not yet supported on Android", Abort); -#endif - QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError)); QVERIFY(!lookup.hostAddressRecords().isEmpty()); QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("aaaa-single")); QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("2001:db8::1")); } -void tst_QDnsLookup::bindingsAndProperties() +void tst_QDnsLookup::setNameserverLoopback() +{ +#ifdef Q_OS_WIN + // Windows doesn't like sending DNS requests to ports other than 53, so + // let's try it first. + constexpr quint16 DesiredPort = 53; +#else + // Trying to bind to port 53 will fail on Unix systems unless this test is + // run as root, so we try mDNS's port (to help decoding in a packet capture). + constexpr quint16 DesiredPort = 5353; // mDNS +#endif + // random loopback address so multiple copies of this test can run + QHostAddress desiredAddress(0x7f000000 | QRandomGenerator::system()->bounded(0xffffff)); + + QUdpSocket server; + if (!server.bind(desiredAddress, DesiredPort)) { + // port in use, try a random one + server.bind(QHostAddress::LocalHost, 0); + } + QCOMPARE(server.state(), QUdpSocket::BoundState); + + QDnsLookup lookup(QDnsLookup::Type::A, u"somelabel.somedomain"_s); + QSignalSpy spy(&lookup, SIGNAL(finished())); + lookup.setNameserver(server.localAddress(), server.localPort()); + + // QDnsLookup is threaded, so we can answer on the main thread + QObject::connect(&server, &QUdpSocket::readyRead, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + QObject::connect(&lookup, &QDnsLookup::finished, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + lookup.lookup(); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY2(spy.isEmpty(), qPrintable(lookup.errorString())); + + QNetworkDatagram dgram = server.receiveDatagram(); + QByteArray data = dgram.data(); + QCOMPARE_GT(data.size(), HeaderSize); + + quint8 opcode = (quint8(data.at(2)) >> 3) & 0xF; + QCOMPARE(opcode, 0); // standard query + + // send an NXDOMAIN reply to release the lookup thread + QByteArray reply = data; + reply[2] = 0x80U; // header->qr = true; + reply[3] = 3; // header->rcode = NXDOMAIN; + server.writeDatagram(reply.constData(), reply.size(), dgram.senderAddress(), + dgram.senderPort()); + server.close(); + + // now check that the QDnsLookup finished + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(spy.size(), 1); + QCOMPARE(lookup.error(), QDnsLookup::NotFoundError); +} + +void tst_QDnsLookup::setNameserver_data() { - QFETCH_GLOBAL(const QString, tld); - if (tld == QStringLiteral("idn")) + static QList<QHostAddress> servers = systemNameservers() + globalPublicNameservers(); + QTest::addColumn<QHostAddress>("server"); + + if (servers.isEmpty()) { + QSKIP("No reachable DNS servers were found"); + } else { + for (const QHostAddress &h : std::as_const(servers)) + QTest::addRow("%s", qUtf8Printable(h.toString())) << h; + } +} + +void tst_QDnsLookup::setNameserver() +{ + QFETCH(QHostAddress, server); + std::unique_ptr<QDnsLookup> lookup = + lookupCommon(QDnsLookup::Type::A, "a-single", server); + if (!lookup) return; + QCOMPARE(lookup->error(), QDnsLookup::NoError); + QString result = formatReply(lookup.get()).join(';'); + QCOMPARE(result, "A 192.0.2.1"); +} +void tst_QDnsLookup::bindingsAndProperties() +{ QDnsLookup lookup; lookup.setType(QDnsLookup::A); @@ -392,7 +626,7 @@ void tst_QDnsLookup::bindingsAndProperties() const QSignalSpy typeChangeSpy(&lookup, &QDnsLookup::typeChanged); dnsTypeProp = QDnsLookup::AAAA; - QCOMPARE(typeChangeSpy.count(), 1); + QCOMPARE(typeChangeSpy.size(), 1); QCOMPARE(lookup.type(), QDnsLookup::AAAA); dnsTypeProp.setBinding(lookup.bindableType().makeBinding()); @@ -404,7 +638,7 @@ void tst_QDnsLookup::bindingsAndProperties() const QSignalSpy nameChangeSpy(&lookup, &QDnsLookup::nameChanged); nameProp = QStringLiteral("a-plus-aaaa"); - QCOMPARE(nameChangeSpy.count(), 1); + QCOMPARE(nameChangeSpy.size(), 1); QCOMPARE(lookup.name(), QStringLiteral("a-plus-aaaa")); nameProp.setBinding(lookup.bindableName().makeBinding()); @@ -414,14 +648,55 @@ void tst_QDnsLookup::bindingsAndProperties() QProperty<QHostAddress> nameserverProp; lookup.bindableNameserver().setBinding(Qt::makePropertyBinding(nameserverProp)); const QSignalSpy nameserverChangeSpy(&lookup, &QDnsLookup::nameserverChanged); + const QSignalSpy nameserverPortChangeSpy(&lookup, &QDnsLookup::nameserverPortChanged); nameserverProp = QHostAddress::LocalHost; - QCOMPARE(nameserverChangeSpy.count(), 1); + QCOMPARE(nameserverChangeSpy.size(), 1); + QCOMPARE(nameserverPortChangeSpy.size(), 0); QCOMPARE(lookup.nameserver(), QHostAddress::LocalHost); nameserverProp.setBinding(lookup.bindableNameserver().makeBinding()); lookup.setNameserver(QHostAddress::Any); QCOMPARE(nameserverProp.value(), QHostAddress::Any); + QCOMPARE(nameserverChangeSpy.size(), 2); + QCOMPARE(nameserverPortChangeSpy.size(), 0); + + lookup.setNameserver(QHostAddress::LocalHostIPv6, 10053); + QCOMPARE(nameserverProp.value(), QHostAddress::LocalHostIPv6); + QCOMPARE(nameserverChangeSpy.size(), 3); + QCOMPARE(nameserverPortChangeSpy.size(), 1); +} + +void tst_QDnsLookup::automatedBindings() +{ + QDnsLookup lookup; + + QTestPrivate::testReadWritePropertyBasics(lookup, u"aaaa"_s, u"txt"_s, "name"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QDnsLookup::name"); + return; + } + + QTestPrivate::testReadWritePropertyBasics(lookup, QDnsLookup::AAAA, QDnsLookup::TXT, "type"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QDnsLookup::type"); + return; + } + + QTestPrivate::testReadWritePropertyBasics(lookup, QHostAddress{QHostAddress::Any}, + QHostAddress{QHostAddress::LocalHost}, + "nameserver"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QDnsLookup::nameserver"); + return; + } + + QTestPrivate::testReadWritePropertyBasics(lookup, quint16(123), quint16(456), + "nameserverPort"); + if (QTest::currentTestFailed()) { + qDebug("Failed property test for QDnsLookup::nameserverPort"); + return; + } } QTEST_MAIN(tst_QDnsLookup) diff --git a/tests/auto/network/kernel/qdnslookup_appless/CMakeLists.txt b/tests/auto/network/kernel/qdnslookup_appless/CMakeLists.txt index 1505228176..41cf19753f 100644 --- a/tests/auto/network/kernel/qdnslookup_appless/CMakeLists.txt +++ b/tests/auto/network/kernel/qdnslookup_appless/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qdnslookup_appless.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qdnslookup_appless Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qdnslookup_appless LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qdnslookup_appless SOURCES tst_qdnslookup_appless.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Network ) diff --git a/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp b/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp index 9346a82dbb..21393ee628 100644 --- a/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp +++ b/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/QCoreApplication> #include <QtNetwork/QDnsLookup> diff --git a/tests/auto/network/kernel/qhostaddress/CMakeLists.txt b/tests/auto/network/kernel/qhostaddress/CMakeLists.txt index a33ae6d709..e11a600b60 100644 --- a/tests/auto/network/kernel/qhostaddress/CMakeLists.txt +++ b/tests/auto/network/kernel/qhostaddress/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qhostaddress.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qhostaddress Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qhostaddress LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qhostaddress SOURCES tst_qhostaddress.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::NetworkPrivate ) @@ -15,6 +22,6 @@ qt_internal_add_test(tst_qhostaddress ##################################################################### qt_internal_extend_target(tst_qhostaddress CONDITION WIN32 - PUBLIC_LIBRARIES + LIBRARIES ws2_32 ) diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 78f072fb54..18d1c04a85 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <qhostaddress.h> #include <private/qhostaddress_p.h> @@ -40,7 +15,7 @@ # include <qt_windows.h> #endif -#ifdef Q_OS_ANDROID +#if defined(Q_OS_ANDROID) || defined(Q_OS_WASM) || defined(Q_OS_VXWORKS) # include <netinet/in.h> #endif @@ -351,6 +326,12 @@ void tst_QHostAddress::isEqual_data() QTest::newRow("anyv6-anyv4-local") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false; QTest::newRow("any-anyv4-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false; QTest::newRow("any-anyv6-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertLocalHost << false; + QTest::newRow("localhostv6-any-tolerant") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::Any) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv4-any-tolerant") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::Any) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv6-anyv6-tolerant") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv4-anyv6-tolerant") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv6-anyv4-tolerant") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv4-anyv4-tolerant") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::TolerantConversion << false; } void tst_QHostAddress::isEqual() @@ -722,6 +703,7 @@ void tst_QHostAddress::classification() bool isUniqueLocalAddress = (result == UniqueLocalAddress); bool isMulticast = (result == MulticastAddress); bool isBroadcast = (result == BroadcastAddress); + bool isPrivateUse = (result == PrivateNetworkAddress || result == UniqueLocalAddress); QCOMPARE(address.isLoopback(), isLoopback); QCOMPARE(address.isGlobal(), isGlobal); @@ -730,6 +712,7 @@ void tst_QHostAddress::classification() QCOMPARE(address.isUniqueLocalUnicast(), isUniqueLocalAddress); QCOMPARE(address.isMulticast(), isMulticast); QCOMPARE(address.isBroadcast(), isBroadcast); + QCOMPARE(address.isPrivateUse(), isPrivateUse); } void tst_QHostAddress::convertv4v6_data() diff --git a/tests/auto/network/kernel/qhostinfo/CMakeLists.txt b/tests/auto/network/kernel/qhostinfo/CMakeLists.txt index 40e0456d5f..dc7ab3b221 100644 --- a/tests/auto/network/kernel/qhostinfo/CMakeLists.txt +++ b/tests/auto/network/kernel/qhostinfo/CMakeLists.txt @@ -1,4 +1,11 @@ -# Generated from qhostinfo.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qhostinfo LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() if(NOT QT_FEATURE_private_tests) return() @@ -11,18 +18,15 @@ endif() qt_internal_add_test(tst_qhostinfo SOURCES tst_qhostinfo.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::NetworkPrivate ) -#### Keys ignored in scope 1:.:.:qhostinfo.pro:<TRUE>: -# _REQUIREMENTS = "qtConfig(private_tests)" - ## Scopes: ##################################################################### qt_internal_extend_target(tst_qhostinfo CONDITION WIN32 - PUBLIC_LIBRARIES + LIBRARIES ws2_32 ) diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index d907ea34aa..bd4bb7ef81 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -1,76 +1,52 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // When using WinSock2 on Windows, it's the first thing that can be included // (except qglobal.h), or else you'll get tons of compile errors #include <qglobal.h> -// To prevent windows system header files from re-defining min/max -#define NOMINMAX 1 - #if defined(Q_OS_WIN) # include <winsock2.h> # include <ws2tcpip.h> #endif -#include <QTest> -#include <QTestEventLoop> -#include <QProcess> +#include <qhostinfo.h> +#include "private/qhostinfo_p.h" +#include "private/qnativesocketengine_p.h" + #include <QCoreApplication> #include <QDebug> -#include <QTcpSocket> #include <QTcpServer> +#include <QTcpSocket> +#include <QTest> +#include <QTestEventLoop> #include <private/qthread_p.h> -#include <time.h> +#include <sys/types.h> + #if defined(Q_OS_WIN) -#include <windows.h> +# include <qt_windows.h> +# ifdef gai_strerror +# undef gai_strerror +# define gai_strerror gai_strerrorA +# endif #else -#include <unistd.h> -#include <signal.h> -#endif - -#include <qhostinfo.h> -#include "private/qhostinfo_p.h" - -#include <sys/types.h> -#if defined(Q_OS_UNIX) -# include <sys/socket.h> # include <netdb.h> +# include <sys/socket.h> +# include <unistd.h> +#endif +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 #endif #include "../../../network-settings.h" #define TEST_DOMAIN ".test.qt-project.org" +using namespace std::chrono_literals; class tst_QHostInfo : public QObject { @@ -109,15 +85,55 @@ private slots: void cache(); void abortHostLookup(); -protected slots: - void resultsReady(const QHostInfo &); private: bool ipv6LookupsAvailable; bool ipv6Available; - bool lookupDone; - int lookupsDoneCounter; +}; + +class tst_QHostInfo_Helper : public QObject +{ + Q_OBJECT +protected slots: + void resultsReady(const QHostInfo &); +public: + tst_QHostInfo_Helper(const QString &hostname) + : hostname(hostname) + {} + + QString hostname; + bool lookupDone = false; + int lookupsDoneCounter = 0; QHostInfo lookupResults; + + void blockingLookup() + { + lookupResults = QHostInfo::fromName(hostname); + lookupDone = true; + ++lookupsDoneCounter; + } + void lookupHostOldStyle() + { + QHostInfo::lookupHost(hostname, this, SLOT(resultsReady(QHostInfo))); + } + void lookupHostNewStyle() + { + QHostInfo::lookupHost(hostname, this, &tst_QHostInfo_Helper::resultsReady); + } + void lookupHostLambda() + { + QHostInfo::lookupHost(hostname, this, [this](const QHostInfo &hostInfo) { + resultsReady(hostInfo); + }); + } + + bool waitForResults(std::chrono::milliseconds timeout = 15s) + { + QTestEventLoop::instance().enterLoop(timeout); + return !QTestEventLoop::instance().timeout() && lookupDone; + } + + void checkResults(QHostInfo::HostInfoError err, const QString &addresses); }; void tst_QHostInfo::swapFunction() @@ -233,26 +249,15 @@ void tst_QHostInfo::lookupIPv4_data() QTest::newRow("idn-unicode") << QString::fromLatin1("a-single.alqualond\353" TEST_DOMAIN) << "192.0.2.1" << int(QHostInfo::NoError); } -void tst_QHostInfo::lookupIPv4() +void tst_QHostInfo_Helper::checkResults(QHostInfo::HostInfoError err, const QString &addresses) { - QFETCH(QString, hostname); - QFETCH(int, err); - QFETCH(QString, addresses); - - lookupDone = false; - QHostInfo::lookupHost(hostname, this, SLOT(resultsReady(QHostInfo))); - - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(lookupDone); - if ((int)lookupResults.error() != (int)err) { qWarning() << hostname << "=>" << lookupResults.errorString(); } - QCOMPARE((int)lookupResults.error(), (int)err); + QCOMPARE(lookupResults.error(), err); QStringList tmp; - for (int i = 0; i < lookupResults.addresses().count(); ++i) + for (int i = 0; i < lookupResults.addresses().size(); ++i) tmp.append(lookupResults.addresses().at(i).toString()); tmp.sort(); @@ -262,6 +267,18 @@ void tst_QHostInfo::lookupIPv4() QCOMPARE(tmp.join(' '), expected.join(' ')); } +void tst_QHostInfo::lookupIPv4() +{ + QFETCH(QString, hostname); + QFETCH(int, err); + QFETCH(QString, addresses); + + tst_QHostInfo_Helper helper(hostname); + helper.lookupHostOldStyle(); + QVERIFY(helper.waitForResults()); + helper.checkResults(QHostInfo::HostInfoError(err), addresses); +} + void tst_QHostInfo::lookupIPv6_data() { QTest::addColumn<QString>("hostname"); @@ -287,24 +304,10 @@ void tst_QHostInfo::lookupIPv6() if (!ipv6LookupsAvailable) QSKIP("This platform does not support IPv6 lookups"); - lookupDone = false; - QHostInfo::lookupHost(hostname, this, SLOT(resultsReady(QHostInfo))); - - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(lookupDone); - - QCOMPARE((int)lookupResults.error(), (int)err); - - QStringList tmp; - for (int i = 0; i < lookupResults.addresses().count(); ++i) - tmp.append(lookupResults.addresses().at(i).toString()); - tmp.sort(); - - QStringList expected = addresses.split(' '); - expected.sort(); - - QCOMPARE(tmp.join(' ').toLower(), expected.join(' ').toLower()); + tst_QHostInfo_Helper helper(hostname); + helper.lookupHostOldStyle(); + QVERIFY(helper.waitForResults()); + helper.checkResults(QHostInfo::HostInfoError(err), addresses); } void tst_QHostInfo::lookupConnectToFunctionPointer_data() @@ -318,26 +321,10 @@ void tst_QHostInfo::lookupConnectToFunctionPointer() QFETCH(int, err); QFETCH(QString, addresses); - lookupDone = false; - QHostInfo::lookupHost(hostname, this, &tst_QHostInfo::resultsReady); - - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(lookupDone); - - if (int(lookupResults.error()) != int(err)) - qWarning() << hostname << "=>" << lookupResults.errorString(); - QCOMPARE(int(lookupResults.error()), int(err)); - - QStringList tmp; - for (const auto &result : lookupResults.addresses()) - tmp.append(result.toString()); - tmp.sort(); - - QStringList expected = addresses.split(' '); - expected.sort(); - - QCOMPARE(tmp.join(' '), expected.join(' ')); + tst_QHostInfo_Helper helper(hostname); + helper.lookupHostNewStyle(); + QVERIFY(helper.waitForResults()); + helper.checkResults(QHostInfo::HostInfoError(err), addresses); } void tst_QHostInfo::lookupConnectToFunctionPointerDeleted() @@ -362,89 +349,38 @@ void tst_QHostInfo::lookupConnectToLambda() QFETCH(int, err); QFETCH(QString, addresses); - lookupDone = false; - QHostInfo::lookupHost(hostname, [this](const QHostInfo &hostInfo) { - resultsReady(hostInfo); - }); - - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(lookupDone); - - if (int(lookupResults.error()) != int(err)) - qWarning() << hostname << "=>" << lookupResults.errorString(); - QCOMPARE(int(lookupResults.error()), int(err)); - - QStringList tmp; - for (int i = 0; i < lookupResults.addresses().count(); ++i) - tmp.append(lookupResults.addresses().at(i).toString()); - tmp.sort(); - - QStringList expected = addresses.split(' '); - expected.sort(); - - QCOMPARE(tmp.join(' '), expected.join(' ')); + tst_QHostInfo_Helper helper(hostname); + helper.lookupHostLambda(); + QVERIFY(helper.waitForResults()); + helper.checkResults(QHostInfo::HostInfoError(err), addresses); } static QStringList reverseLookupHelper(const QString &ip) { QStringList results; - - const QString pythonCode = - "import socket;" - "import sys;" - "print (socket.getnameinfo((sys.argv[1], 0), 0)[0]);"; - - QList<QByteArray> lines; - QProcess python; - python.setProcessChannelMode(QProcess::ForwardedErrorChannel); - python.start("python", QStringList() << QString("-c") << pythonCode << ip); - if (python.waitForFinished()) { - if (python.exitStatus() == QProcess::NormalExit && python.exitCode() == 0) - lines = python.readAllStandardOutput().split('\n'); - for (QByteArray line : lines) { - if (!line.isEmpty()) - results << line.trimmed(); - } - if (!results.isEmpty()) - return results; - } - - qDebug() << "Python failed, falling back to nslookup"; - QProcess lookup; - lookup.setProcessChannelMode(QProcess::ForwardedErrorChannel); - lookup.start("nslookup", QStringList(ip)); - if (!lookup.waitForFinished()) { - results << "nslookup failure"; - qDebug() << "nslookup failure"; + union qt_sockaddr { + sockaddr a; + sockaddr_in a4; + sockaddr_in6 a6; + } sa = {}; + + QHostAddress addr(ip); + if (addr.isNull()) { + qWarning("Could not parse IP address: %ls", qUtf16Printable(ip)); return results; } - lines = lookup.readAllStandardOutput().split('\n'); - - QByteArray name; - - const QByteArray nameMarkerNix("name ="); - const QByteArray nameMarkerWin("Name:"); - const QByteArray addressMarkerWin("Address:"); - - for (QByteArray line : lines) { - int index = -1; - if ((index = line.indexOf(nameMarkerNix)) != -1) { // Linux and macOS - name = line.mid(index + nameMarkerNix.length()).chopped(1).trimmed(); - results << name; - } else if (line.startsWith(nameMarkerWin)) { // Windows formatting - name = line.mid(line.lastIndexOf(" ")).trimmed(); - } else if (line.startsWith(addressMarkerWin)) { - QByteArray address = line.mid(addressMarkerWin.length()).trimmed(); - if (address == ip.toUtf8()) { - results << name; - } - } - } - if (results.isEmpty()) { - qDebug() << "Failure to parse nslookup output: " << lines; + // from qnativesocketengine_p.h: + QT_SOCKLEN_T len = setSockaddr(&sa.a, addr, /*port = */ 0); + + QByteArray name(NI_MAXHOST, Qt::Uninitialized); + int ni_flags = NI_NAMEREQD | NI_NUMERICSERV; + if (int r = getnameinfo(&sa.a, len, name.data(), name.size(), nullptr, 0, ni_flags)) { + qWarning("Failed to reverse look up '%ls': %s", qUtf16Printable(ip), gai_strerror(r)); + } else { + results << QString::fromLatin1(name, qstrnlen(name, name.size())); } + return results; } @@ -457,8 +393,10 @@ void tst_QHostInfo::reverseLookup_data() QTest::newRow("dns.google") << QString("8.8.8.8") << reverseLookupHelper("8.8.8.8") << 0 << false; QTest::newRow("one.one.one.one") << QString("1.1.1.1") << reverseLookupHelper("1.1.1.1") << 0 << false; - QTest::newRow("dns.google IPv6") << QString("2001:4860:4860::8888") << reverseLookupHelper("2001:4860:4860::8888") << 0 << true; - QTest::newRow("cloudflare IPv6") << QString("2606:4700:4700::1111") << reverseLookupHelper("2606:4700:4700::1111") << 0 << true; + if (QStringList hostNames = reverseLookupHelper("2001:4860:4860::8888"); !hostNames.isEmpty()) + QTest::newRow("dns.google IPv6") << QString("2001:4860:4860::8888") << std::move(hostNames) << 0 << true; + if (QStringList hostNames = reverseLookupHelper("2606:4700:4700::1111"); !hostNames.isEmpty()) + QTest::newRow("cloudflare IPv6") << QString("2606:4700:4700::1111") << std::move(hostNames) << 0 << true; QTest::newRow("bogus-name IPv6") << QString("1::2::3::4") << QStringList() << 1 << true; } @@ -467,11 +405,6 @@ void tst_QHostInfo::reverseLookup() QFETCH(QString, address); QFETCH(QStringList, hostNames); QFETCH(int, err); - QFETCH(bool, ipv6); - - if (ipv6 && !ipv6LookupsAvailable) { - QSKIP("IPv6 reverse lookups are not supported on this platform"); - } QHostInfo info = QHostInfo::fromName(address); @@ -479,7 +412,7 @@ void tst_QHostInfo::reverseLookup() if (!hostNames.contains(info.hostName())) qDebug() << "Failure: expecting" << hostNames << ",got " << info.hostName(); QVERIFY(hostNames.contains(info.hostName())); - QCOMPARE(info.addresses().first(), QHostAddress(address)); + QCOMPARE(info.addresses().constFirst(), QHostAddress(address)); } else { QCOMPARE(info.hostName(), address); QCOMPARE(info.error(), QHostInfo::HostNotFound); @@ -500,21 +433,9 @@ void tst_QHostInfo::blockingLookup() QFETCH(int, err); QFETCH(QString, addresses); - QHostInfo hostInfo = QHostInfo::fromName(hostname); - QStringList tmp; - for (int i = 0; i < hostInfo.addresses().count(); ++i) - tmp.append(hostInfo.addresses().at(i).toString()); - tmp.sort(); - - if ((int)hostInfo.error() != (int)err) { - qWarning() << hostname << "=>" << lookupResults.errorString(); - } - QCOMPARE((int)hostInfo.error(), (int)err); - - QStringList expected = addresses.split(' '); - expected.sort(); - - QCOMPARE(tmp.join(' ').toUpper(), expected.join(' ').toUpper()); + tst_QHostInfo_Helper helper(hostname); + helper.blockingLookup(); + helper.checkResults(QHostInfo::HostInfoError(err), addresses); } void tst_QHostInfo::raceCondition() @@ -531,8 +452,9 @@ protected: inline void run() override { QHostInfo info = QHostInfo::fromName("a-single" TEST_DOMAIN); + QCOMPARE(info.errorString(), "Unknown error"); // no error QCOMPARE(info.error(), QHostInfo::NoError); - QVERIFY(info.addresses().count() > 0); + QVERIFY(info.addresses().size() > 0); QCOMPARE(info.addresses().at(0).toString(), QString("192.0.2.1")); } }; @@ -579,24 +501,22 @@ void tst_QHostInfo::threadSafetyAsynchronousAPI() { const int nattempts = 10; const int lookupsperthread = 10; - QList<QThread*> threads; - QList<LookupReceiver*> receivers; + QThread threads[nattempts]; + LookupReceiver receivers[nattempts]; for (int i = 0; i < nattempts; ++i) { - QThread* thread = new QThread; - LookupReceiver* receiver = new LookupReceiver; + QThread *thread = &threads[i]; + LookupReceiver *receiver = &receivers[i]; receiver->numrequests = lookupsperthread; - receivers.append(receiver); receiver->moveToThread(thread); connect(thread, SIGNAL(started()), receiver, SLOT(start())); thread->start(); - threads.append(thread); } - for (int k = threads.count() - 1; k >= 0; --k) - QVERIFY(threads.at(k)->wait(60000)); - foreach (LookupReceiver* receiver, receivers) { - QCOMPARE(receiver->result.error(), QHostInfo::NoError); - QCOMPARE(receiver->result.addresses().at(0).toString(), QString("192.0.2.1")); - QCOMPARE(receiver->numrequests, 0); + for (int k = nattempts - 1; k >= 0; --k) + QVERIFY(threads[k].wait(60000)); + for (LookupReceiver &receiver : receivers) { + QCOMPARE(receiver.result.error(), QHostInfo::NoError); + QCOMPARE(receiver.result.addresses().at(0).toString(), QString("192.0.2.1")); + QCOMPARE(receiver.numrequests, 0); } } @@ -605,17 +525,11 @@ void tst_QHostInfo::threadSafetyAsynchronousAPI() void tst_QHostInfo::multipleSameLookups() { const int COUNT = 10; - lookupsDoneCounter = 0; - + tst_QHostInfo_Helper helper("localhost"); for (int i = 0; i < COUNT; i++) - QHostInfo::lookupHost("localhost", this, SLOT(resultsReady(QHostInfo))); + helper.lookupHostOldStyle(); - QElapsedTimer timer; - timer.start(); - while (timer.elapsed() < 10000 && lookupsDoneCounter < COUNT) { - QTestEventLoop::instance().enterLoop(2); - } - QCOMPARE(lookupsDoneCounter, COUNT); + QTRY_COMPARE_WITH_TIMEOUT(helper.lookupsDoneCounter, COUNT, 10s); } // this test is for the multi-threaded QHostInfo rewrite. It is about getting results at all, @@ -644,19 +558,15 @@ void tst_QHostInfo::multipleDifferentLookups() QFETCH(int, repeats); const int COUNT = hostnameList.size(); - lookupsDoneCounter = 0; + tst_QHostInfo_Helper helper(QString{}); for (int i = 0; i < hostnameList.size(); i++) - for (int j = 0; j < repeats; ++j) - QHostInfo::lookupHost(hostnameList.at(i), this, SLOT(resultsReady(QHostInfo))); - - QElapsedTimer timer; - timer.start(); - while (timer.elapsed() < 60000 && lookupsDoneCounter < repeats*COUNT) { - QTestEventLoop::instance().enterLoop(2); - //qDebug() << "t:" << timer.elapsed(); - } - QCOMPARE(lookupsDoneCounter, repeats*COUNT); + for (int j = 0; j < repeats; ++j) { + helper.hostname = hostnameList.at(i); + helper.lookupHostOldStyle(); + } + + QTRY_COMPARE_WITH_TIMEOUT(helper.lookupsDoneCounter, repeats*COUNT, 60s); } void tst_QHostInfo::cache() @@ -665,13 +575,12 @@ void tst_QHostInfo::cache() if (!cache) return; // test makes only sense when cache enabled - // reset slot counter - lookupsDoneCounter = 0; + tst_QHostInfo_Helper helper("localhost"); // lookup once, wait in event loop, result should not come directly. bool valid = true; int id = -1; - QHostInfo result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id); + QHostInfo result = qt_qhostinfo_lookup(helper.hostname, &helper, SLOT(resultsReady(QHostInfo)), &valid, &id); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(!valid); @@ -679,7 +588,7 @@ void tst_QHostInfo::cache() // loopkup second time, result should come directly valid = false; - result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id); + result = qt_qhostinfo_lookup(helper.hostname, &helper, SLOT(resultsReady(QHostInfo)), &valid, &id); QVERIFY(valid); QVERIFY(!result.addresses().isEmpty()); @@ -688,17 +597,17 @@ void tst_QHostInfo::cache() // lookup third time, result should not come directly. valid = true; - result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id); + result = qt_qhostinfo_lookup(helper.hostname, &helper, SLOT(resultsReady(QHostInfo)), &valid, &id); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(!valid); QVERIFY(result.addresses().isEmpty()); // the slot should have been called 2 times. - QCOMPARE(lookupsDoneCounter, 2); + QCOMPARE(helper.lookupsDoneCounter, 2); } -void tst_QHostInfo::resultsReady(const QHostInfo &hi) +void tst_QHostInfo_Helper::resultsReady(const QHostInfo &hi) { QVERIFY(QThread::currentThread() == thread()); lookupDone = true; @@ -709,16 +618,15 @@ void tst_QHostInfo::resultsReady(const QHostInfo &hi) void tst_QHostInfo::abortHostLookup() { - //reset counter - lookupsDoneCounter = 0; + tst_QHostInfo_Helper helper("a-single" TEST_DOMAIN); bool valid = false; int id = -1; - QHostInfo result = qt_qhostinfo_lookup("a-single" TEST_DOMAIN, this, SLOT(resultsReady(QHostInfo)), &valid, &id); + QHostInfo result = qt_qhostinfo_lookup(helper.hostname, &helper, SLOT(resultsReady(QHostInfo)), &valid, &id); QVERIFY(!valid); //it is assumed that the DNS request/response in the backend is slower than it takes to call abort QHostInfo::abortHostLookup(id); QTestEventLoop::instance().enterLoop(5); - QCOMPARE(lookupsDoneCounter, 0); + QCOMPARE(helper.lookupsDoneCounter, 0); } class LookupAborter : public QObject diff --git a/tests/auto/network/kernel/qnetworkaddressentry/CMakeLists.txt b/tests/auto/network/kernel/qnetworkaddressentry/CMakeLists.txt index bc9463aa13..02bf37880a 100644 --- a/tests/auto/network/kernel/qnetworkaddressentry/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkaddressentry/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qnetworkaddressentry.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qnetworkaddressentry Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkaddressentry LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkaddressentry SOURCES tst_qnetworkaddressentry.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Network ) diff --git a/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp b/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp index 097d53caf5..801eb58931 100644 --- a/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp +++ b/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/network/kernel/qnetworkdatagram/CMakeLists.txt b/tests/auto/network/kernel/qnetworkdatagram/CMakeLists.txt index 13dcbcb2e3..5bfc2edc6a 100644 --- a/tests/auto/network/kernel/qnetworkdatagram/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkdatagram/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qnetworkdatagram.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qnetworkdatagram Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkdatagram LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkdatagram SOURCES tst_qnetworkdatagram.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Network ) diff --git a/tests/auto/network/kernel/qnetworkdatagram/tst_qnetworkdatagram.cpp b/tests/auto/network/kernel/qnetworkdatagram/tst_qnetworkdatagram.cpp index a15272caa6..df473133a6 100644 --- a/tests/auto/network/kernel/qnetworkdatagram/tst_qnetworkdatagram.cpp +++ b/tests/auto/network/kernel/qnetworkdatagram/tst_qnetworkdatagram.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QNetworkDatagram> #include <QTest> diff --git a/tests/auto/network/kernel/qnetworkinformation/CMakeLists.txt b/tests/auto/network/kernel/qnetworkinformation/CMakeLists.txt index f0c37913a8..354cefc993 100644 --- a/tests/auto/network/kernel/qnetworkinformation/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkinformation/CMakeLists.txt @@ -1,6 +1,15 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkinformation LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkinformation SOURCES tst_qnetworkinformation.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::NetworkPrivate ) diff --git a/tests/auto/network/kernel/qnetworkinformation/tst_qnetworkinformation.cpp b/tests/auto/network/kernel/qnetworkinformation/tst_qnetworkinformation.cpp index b78983ae40..daf81823e8 100644 --- a/tests/auto/network/kernel/qnetworkinformation/tst_qnetworkinformation.cpp +++ b/tests/auto/network/kernel/qnetworkinformation/tst_qnetworkinformation.cpp @@ -1,34 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtNetwork/private/qnetworkinformation_p.h> #include <QtNetwork/qnetworkinformation.h> #include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> #include <limits> #include <memory> @@ -43,6 +19,7 @@ private slots: void reachability(); void behindCaptivePortal(); void transportMedium(); + void isMetered(); void cleanupTestCase(); private: @@ -88,11 +65,18 @@ public: instance->setTransportMedium(medium); } + static void setNewMetered(bool metered) + { + Q_ASSERT(instance); + instance->setMetered(metered); + } + static QNetworkInformation::Features featuresSupportedStatic() { return { QNetworkInformation::Feature::Reachability | QNetworkInformation::Feature::CaptivePortal - | QNetworkInformation::Feature::TransportMedium }; + | QNetworkInformation::Feature::TransportMedium + | QNetworkInformation::Feature::Metered }; } private: @@ -126,10 +110,10 @@ void tst_QNetworkInformation::initTestCase() auto backends = QNetworkInformation::availableBackends(); QVERIFY(backends.size() > prevBackends.size()); QVERIFY(backends.contains(u"mock")); - QVERIFY(QNetworkInformation::load(u"mock")); - QVERIFY(QNetworkInformation::load(u"mock")); - QVERIFY(QNetworkInformation::load(u"mOcK")); - QVERIFY(!QNetworkInformation::load(u"mocks")); + QVERIFY(QNetworkInformation::loadBackendByName(u"mock")); + QVERIFY(QNetworkInformation::loadBackendByName(u"mock")); + QVERIFY(QNetworkInformation::loadBackendByName(u"mOcK")); + QVERIFY(!QNetworkInformation::loadBackendByName(u"mocks")); } void tst_QNetworkInformation::cleanupTestCase() @@ -144,9 +128,10 @@ void tst_QNetworkInformation::supportedFeatures() { auto info = QNetworkInformation::instance(); - auto allFeatures = QNetworkInformation::Features( - QNetworkInformation::Feature::CaptivePortal | QNetworkInformation::Feature::Reachability - | QNetworkInformation::Feature::TransportMedium); + auto allFeatures = QNetworkInformation::Features(QNetworkInformation::Feature::CaptivePortal + | QNetworkInformation::Feature::Reachability + | QNetworkInformation::Feature::TransportMedium + | QNetworkInformation::Feature::Metered); QCOMPARE(info->supportedFeatures(), allFeatures); @@ -154,6 +139,7 @@ void tst_QNetworkInformation::supportedFeatures() QVERIFY(info->supports(QNetworkInformation::Feature::CaptivePortal)); QVERIFY(info->supports(QNetworkInformation::Feature::Reachability)); QVERIFY(info->supports(QNetworkInformation::Feature::TransportMedium)); + QVERIFY(info->supports(QNetworkInformation::Feature::Metered)); } void tst_QNetworkInformation::reachability() @@ -248,5 +234,22 @@ void tst_QNetworkInformation::transportMedium() QVERIFY(!signalEmitted); } +void tst_QNetworkInformation::isMetered() +{ + auto info = QNetworkInformation::instance(); + + QSignalSpy spy(info, &QNetworkInformation::isMeteredChanged); + QVERIFY(!info->isMetered()); + MockBackend::setNewMetered(true); + QCOMPARE(spy.size(), 1); + QVERIFY(info->isMetered()); + QVERIFY(spy[0][0].toBool()); + spy.clear(); + + // Set the same value again, signal should not be emitted again + MockBackend::setNewMetered(true); + QCOMPARE(spy.size(), 0); +} + QTEST_MAIN(tst_QNetworkInformation); #include "tst_qnetworkinformation.moc" diff --git a/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt b/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt index 76cbf594c3..d4a2e486bd 100644 --- a/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt @@ -1,6 +1,15 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkinformation_appless LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkinformation_appless SOURCES tst_qnetworkinformation_appless.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Network ) diff --git a/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp b/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp index ff058e8a9b..b08843314a 100644 --- a/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp +++ b/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/qcoreapplication.h> #include <QtNetwork/qnetworkinformation.h> @@ -48,7 +23,7 @@ void tst_QNetworkInformation_appless::reinit() if (QNetworkInformation::availableBackends().isEmpty()) QSKIP("No backends available!"); - QVERIFY(QNetworkInformation::load(QNetworkInformation::Feature::Reachability)); + QVERIFY(QNetworkInformation::loadDefaultBackend()); auto info = QNetworkInformation::instance(); QVERIFY(info); } @@ -57,7 +32,7 @@ void tst_QNetworkInformation_appless::reinit() { QCoreApplication app(argc, argv); - QVERIFY(QNetworkInformation::load(QNetworkInformation::Feature::Reachability)); + QVERIFY(QNetworkInformation::loadDefaultBackend()); auto info = QNetworkInformation::instance(); QVERIFY(info); } diff --git a/tests/auto/network/kernel/qnetworkinterface/CMakeLists.txt b/tests/auto/network/kernel/qnetworkinterface/CMakeLists.txt index 0c667781e9..3e5dab63e0 100644 --- a/tests/auto/network/kernel/qnetworkinterface/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkinterface/CMakeLists.txt @@ -1,12 +1,20 @@ -# Generated from qnetworkinterface.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qnetworkinterface Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkinterface LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkinterface SOURCES tst_qnetworkinterface.cpp - PUBLIC_LIBRARIES - Qt::Network + LIBRARIES + Qt::NetworkPrivate + QT_TEST_SERVER_LIST "apache2" ) diff --git a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp index e18c50afbd..141ca25021 100644 --- a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp @@ -1,41 +1,18 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QtEndian> +#include <QSet> #include <qcoreapplication.h> #include <qnetworkinterface.h> #include <qudpsocket.h> #include "../../../network-settings.h" +#include <private/qtnetwork-config_p.h> + Q_DECLARE_METATYPE(QHostAddress) class tst_QNetworkInterface : public QObject @@ -59,6 +36,8 @@ private slots: void interfaceFromXXX_data(); void interfaceFromXXX(); void copyInvalidInterface(); +private: + bool hasNetworkServer = false; }; tst_QNetworkInterface::tst_QNetworkInterface() @@ -71,22 +50,29 @@ tst_QNetworkInterface::~tst_QNetworkInterface() bool tst_QNetworkInterface::isIPv6Working() { - QUdpSocket socket; - socket.connectToHost(QHostAddress::LocalHostIPv6, 1234); - return socket.state() == QAbstractSocket::ConnectedState || socket.waitForConnected(100); + // QNetworkInterface may be unable to detect IPv6 addresses even if they + // are there, due to limitations of the implementation. + if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows || + QT_CONFIG(linux_netlink) || (QT_CONFIG(getifaddrs) && QT_CONFIG(ipv6ifname))) { + return QtNetworkSettings::hasIPv6(); + } + return false; } void tst_QNetworkInterface::initTestCase() { - if (!QtNetworkSettings::verifyTestNetworkSettings()) - QSKIP("No network test server available"); +#ifdef QT_TEST_SERVER + hasNetworkServer = QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80); +#else + hasNetworkServer = QtNetworkSettings::verifyTestNetworkSettings(); +#endif } void tst_QNetworkInterface::dump() { // This is for manual testing: - QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); - foreach (const QNetworkInterface &i, allInterfaces) { + const QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface &i : allInterfaces) { QString flags; if (i.flags() & QNetworkInterface::IsUp) flags += "Up,"; if (i.flags() & QNetworkInterface::IsRunning) flags += "Running,"; @@ -113,7 +99,8 @@ void tst_QNetworkInterface::dump() qDebug() << " MTU: " << i.maximumTransmissionUnit(); int count = 0; - foreach (const QNetworkAddressEntry &e, i.addressEntries()) { + const auto entries = i.addressEntries(); + for (const QNetworkAddressEntry &e : entries) { QDebug s = qDebug(); s.nospace() << " address " << qSetFieldWidth(2) << count++ << qSetFieldWidth(0); @@ -139,11 +126,11 @@ void tst_QNetworkInterface::dump() void tst_QNetworkInterface::consistencyCheck() { - QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces(); + const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces(); QSet<QString> interfaceNames; QList<int> interfaceIndexes; - foreach (const QNetworkInterface &iface, ifaces) { + for (const QNetworkInterface &iface : ifaces) { QVERIFY(iface.isValid()); QVERIFY2(!interfaceNames.contains(iface.name()), "duplicate name = " + iface.name().toLocal8Bit()); @@ -189,7 +176,8 @@ void tst_QNetworkInterface::localAddress_data() if (ipv6) QTest::newRow("localhost-ipv6") << QHostAddress(QHostAddress::LocalHostIPv6); - QTest::newRow("test-server") << QtNetworkSettings::serverIP(); + if (hasNetworkServer) + QTest::newRow("test-server") << QtNetworkSettings::httpServerIp(); QSet<QHostAddress> added; const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces(); @@ -263,10 +251,10 @@ void tst_QNetworkInterface::interfaceFromXXX_data() { QTest::addColumn<QNetworkInterface>("iface"); - QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); - if (allInterfaces.count() == 0) + const QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); + if (allInterfaces.size() == 0) QSKIP("No interfaces to test!"); - foreach (QNetworkInterface iface, allInterfaces) + for (const QNetworkInterface &iface : allInterfaces) QTest::newRow(iface.name().toLocal8Bit()) << iface; } @@ -280,7 +268,8 @@ void tst_QNetworkInterface::interfaceFromXXX() QCOMPARE(QNetworkInterface::interfaceNameFromIndex(idx), iface.name()); QCOMPARE(QNetworkInterface::interfaceIndexFromName(iface.name()), idx); } - foreach (QNetworkAddressEntry entry, iface.addressEntries()) { + const auto entries = iface.addressEntries(); + for (const QNetworkAddressEntry &entry : entries) { QVERIFY(!entry.ip().isNull()); if (!entry.netmask().isNull()) { diff --git a/tests/auto/network/kernel/qnetworkproxy/CMakeLists.txt b/tests/auto/network/kernel/qnetworkproxy/CMakeLists.txt index 40650726a7..629bfb0a8a 100644 --- a/tests/auto/network/kernel/qnetworkproxy/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkproxy/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qnetworkproxy.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qnetworkproxy Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkproxy LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkproxy SOURCES tst_qnetworkproxy.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Network ) diff --git a/tests/auto/network/kernel/qnetworkproxy/tst_qnetworkproxy.cpp b/tests/auto/network/kernel/qnetworkproxy/tst_qnetworkproxy.cpp index 5ec60fb5b2..1f00f8d054 100644 --- a/tests/auto/network/kernel/qnetworkproxy/tst_qnetworkproxy.cpp +++ b/tests/auto/network/kernel/qnetworkproxy/tst_qnetworkproxy.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/BLACKLIST b/tests/auto/network/kernel/qnetworkproxyfactory/BLACKLIST deleted file mode 100644 index 6e9d9ffdec..0000000000 --- a/tests/auto/network/kernel/qnetworkproxyfactory/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -# QTBUG-87385 -[genericSystemProxy] -android diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/CMakeLists.txt b/tests/auto/network/kernel/qnetworkproxyfactory/CMakeLists.txt index e9e2d8ae0b..41dae6a02a 100644 --- a/tests/auto/network/kernel/qnetworkproxyfactory/CMakeLists.txt +++ b/tests/auto/network/kernel/qnetworkproxyfactory/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qnetworkproxyfactory.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qnetworkproxyfactory Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qnetworkproxyfactory LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qnetworkproxyfactory SOURCES tst_qnetworkproxyfactory.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::NetworkPrivate ) diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index 8b64788a73..c38a480766 100644 --- a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -1,31 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/QTest> #include <QtTest/QTestEventLoop> @@ -119,7 +93,8 @@ void tst_QNetworkProxyFactory::systemProxyForQuery_data() QTest::newRow("autobind-server") << (int)QNetworkProxyQuery::TcpServer << QUrl() << QString() << QString() << 0 << (int)QNetworkProxy::ListeningCapability; QTest::newRow("web-server") << (int)QNetworkProxyQuery::TcpServer << QUrl() << QString() << QString() << 80 << (int)QNetworkProxy::ListeningCapability; //windows: these should be bypassed if "bypass proxy server for local addresses" is ticked - foreach (QHostAddress address, QNetworkInterface::allAddresses()) { + const auto addresses = QNetworkInterface::allAddresses(); + for (const QHostAddress &address : addresses) { QTest::newRow(qPrintable(address.toString())) << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString() << address.toString() << 0 << 0; } @@ -172,16 +147,15 @@ void tst_QNetworkProxyFactory::systemProxyForQuery() const QElapsedTimer sw; sw.start(); - QList<QNetworkProxy> systemProxyList = QNetworkProxyFactory::systemProxyForQuery(query); + const QList<QNetworkProxy> systemProxyList = QNetworkProxyFactory::systemProxyForQuery(query); qDebug() << sw.elapsed() << "ms"; QVERIFY(!systemProxyList.isEmpty()); // for manual comparison with system qDebug() << systemProxyList; - foreach (const QNetworkProxy &proxy, systemProxyList) { + for (const QNetworkProxy &proxy : systemProxyList) QVERIFY((requiredCapabilities == 0) || (proxy.capabilities() & requiredCapabilities)); - } } void tst_QNetworkProxyFactory::systemProxyForQuery_local() @@ -256,8 +230,6 @@ void tst_QNetworkProxyFactory::genericSystemProxy() QFETCH(QString, hostName); QFETCH(int, port); -// We can only use the generic system proxy where available: -#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) && !QT_CONFIG(libproxy) qputenv(envVar, url); const QList<QNetworkProxy> systemProxy = QNetworkProxyFactory::systemProxyForQuery(); QCOMPARE(systemProxy.size(), 1); @@ -265,18 +237,14 @@ void tst_QNetworkProxyFactory::genericSystemProxy() QCOMPARE(systemProxy.first().hostName(), hostName); QCOMPARE(systemProxy.first().port(), static_cast<quint16>(port)); qunsetenv(envVar); -#else - Q_UNUSED(envVar); - Q_UNUSED(url); - Q_UNUSED(proxyType); - Q_UNUSED(hostName); - Q_UNUSED(port); - QSKIP("Generic system proxy not available on this platform."); -#endif } void tst_QNetworkProxyFactory::genericSystemProxy_data() { + // We can only use the generic system proxy where available: +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) || defined(Q_OS_ANDROID) || QT_CONFIG(libproxy) + QSKIP("Generic system proxy not available on this platform."); +#else QTest::addColumn<QByteArray>("envVar"); QTest::addColumn<QByteArray>("url"); QTest::addColumn<QNetworkProxy::ProxyType>("proxyType"); @@ -289,6 +257,7 @@ void tst_QNetworkProxyFactory::genericSystemProxy_data() << QNetworkProxy::Socks5Proxy << QString("127.0.0.1") << 4242; QTest::newRow("http") << QByteArray("http_proxy") << QByteArray("http://example.com:666") << QNetworkProxy::HttpProxy << QString("example.com") << 666; +#endif } class QSPFQThread : public QThread |