mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-04 00:05:25 +08:00
qt 6.5.1 original
This commit is contained in:
23
tests/auto/network/kernel/CMakeLists.txt
Normal file
23
tests/auto/network/kernel/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT INTEGRITY)
|
||||
add_subdirectory(qdnslookup)
|
||||
add_subdirectory(qdnslookup_appless)
|
||||
endif()
|
||||
if(QT_FEATURE_networkinterface)
|
||||
add_subdirectory(qnetworkproxyfactory)
|
||||
add_subdirectory(qnetworkinterface)
|
||||
endif()
|
||||
add_subdirectory(qnetworkproxy)
|
||||
add_subdirectory(qnetworkdatagram)
|
||||
add_subdirectory(qnetworkaddressentry)
|
||||
add_subdirectory(qhostaddress)
|
||||
if(QT_FEATURE_private_tests AND NOT MACOS AND NOT INTEGRITY)
|
||||
add_subdirectory(qhostinfo)
|
||||
endif()
|
||||
if(QT_FEATURE_private_tests)
|
||||
add_subdirectory(qauthenticator)
|
||||
add_subdirectory(qnetworkinformation)
|
||||
add_subdirectory(qnetworkinformation_appless)
|
||||
endif()
|
17
tests/auto/network/kernel/qauthenticator/CMakeLists.txt
Normal file
17
tests/auto/network/kernel/qauthenticator/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
## tst_qauthenticator Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qauthenticator
|
||||
SOURCES
|
||||
tst_qauthenticator.cpp
|
||||
LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
192
tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp
Normal file
192
tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QTest>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtNetwork/QAuthenticator>
|
||||
|
||||
#include <private/qauthenticator_p.h>
|
||||
|
||||
class tst_QAuthenticator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QAuthenticator();
|
||||
|
||||
private Q_SLOTS:
|
||||
void basicAuth();
|
||||
void basicAuth_data();
|
||||
|
||||
void ntlmAuth_data();
|
||||
void ntlmAuth();
|
||||
|
||||
void sha256AndMd5Digest();
|
||||
|
||||
void equalityOperators();
|
||||
|
||||
void isMethodSupported();
|
||||
};
|
||||
|
||||
tst_QAuthenticator::tst_QAuthenticator()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QAuthenticator::basicAuth_data()
|
||||
{
|
||||
QTest::addColumn<QString>("data");
|
||||
QTest::addColumn<QString>("realm");
|
||||
QTest::addColumn<QString>("user");
|
||||
QTest::addColumn<QString>("password");
|
||||
QTest::addColumn<QByteArray>("expectedReply");
|
||||
|
||||
QTest::newRow("just-user") << "" << "" << "foo" << "" << QByteArray("foo:").toBase64();
|
||||
QTest::newRow("user-password") << "" << "" << "foo" << "bar" << QByteArray("foo:bar").toBase64();
|
||||
QTest::newRow("user-password-realm") << "realm=\"secure area\"" << "secure area" << "foo" << "bar" << QByteArray("foo:bar").toBase64();
|
||||
}
|
||||
|
||||
void tst_QAuthenticator::basicAuth()
|
||||
{
|
||||
QFETCH(QString, data);
|
||||
QFETCH(QString, realm);
|
||||
QFETCH(QString, user);
|
||||
QFETCH(QString, password);
|
||||
QFETCH(QByteArray, expectedReply);
|
||||
|
||||
QAuthenticator auth;
|
||||
auth.detach();
|
||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth);
|
||||
QCOMPARE(priv->phase, QAuthenticatorPrivate::Start);
|
||||
|
||||
QList<QPair<QByteArray, QByteArray> > headers;
|
||||
headers << qMakePair(QByteArray("WWW-Authenticate"), "Basic " + data.toUtf8());
|
||||
priv->parseHttpResponse(headers, /*isProxy = */ false, {});
|
||||
|
||||
QCOMPARE(auth.realm(), realm);
|
||||
QCOMPARE(auth.option("realm").toString(), realm);
|
||||
|
||||
auth.setUser(user);
|
||||
auth.setPassword(password);
|
||||
|
||||
QCOMPARE(priv->phase, QAuthenticatorPrivate::Start);
|
||||
|
||||
QCOMPARE(priv->calculateResponse("GET", "/", u"").constData(), QByteArray("Basic " + expectedReply).constData());
|
||||
}
|
||||
|
||||
void tst_QAuthenticator::ntlmAuth_data()
|
||||
{
|
||||
QTest::addColumn<QString>("data");
|
||||
QTest::addColumn<QString>("realm");
|
||||
QTest::addColumn<bool>("sso");
|
||||
|
||||
QTest::newRow("no-realm") << "TlRMTVNTUAACAAAAHAAcADAAAAAFAoEATFZ3OLRQADIAAAAAAAAAAJYAlgBMAAAAUQBUAC0AVABFAFMAVAAtAEQATwBNAEEASQBOAAIAHABRAFQALQBUAEUAUwBUAC0ARABPAE0AQQBJAE4AAQAcAFEAVAAtAFQARQBTAFQALQBTAEUAUgBWAEUAUgAEABYAcQB0AC0AdABlAHMAdAAtAG4AZQB0AAMANABxAHQALQB0AGUAcwB0AC0AcwBlAHIAdgBlAHIALgBxAHQALQB0AGUAcwB0AC0AbgBlAHQAAAAAAA==" << "" << false;
|
||||
QTest::newRow("with-realm") << "TlRMTVNTUAACAAAADAAMADgAAAAFAoECWCZkccFFAzwAAAAAAAAAAL4AvgBEAAAABQLODgAAAA9NAEcARABOAE8ASwACAAwATQBHAEQATgBPAEsAAQAcAE4ATwBLAC0AQQBNAFMAUwBTAEYARQAtADAAMQAEACAAbQBnAGQAbgBvAGsALgBuAG8AawBpAGEALgBjAG8AbQADAD4AbgBvAGsALQBhAG0AcwBzAHMAZgBlAC0AMAAxAC4AbQBnAGQAbgBvAGsALgBuAG8AawBpAGEALgBjAG8AbQAFACAAbQBnAGQAbgBvAGsALgBuAG8AawBpAGEALgBjAG8AbQAAAAAA" << "NOE" << false;
|
||||
QTest::newRow("no-realm-sso") << "TlRMTVNTUAACAAAAHAAcADAAAAAFAoEATFZ3OLRQADIAAAAAAAAAAJYAlgBMAAAAUQBUAC0AVABFAFMAVAAtAEQATwBNAEEASQBOAAIAHABRAFQALQBUAEUAUwBUAC0ARABPAE0AQQBJAE4AAQAcAFEAVAAtAFQARQBTAFQALQBTAEUAUgBWAEUAUgAEABYAcQB0AC0AdABlAHMAdAAtAG4AZQB0AAMANABxAHQALQB0AGUAcwB0AC0AcwBlAHIAdgBlAHIALgBxAHQALQB0AGUAcwB0AC0AbgBlAHQAAAAAAA==" << "" << true;
|
||||
QTest::newRow("with-realm-sso") << "TlRMTVNTUAACAAAADAAMADgAAAAFAoECWCZkccFFAzwAAAAAAAAAAL4AvgBEAAAABQLODgAAAA9NAEcARABOAE8ASwACAAwATQBHAEQATgBPAEsAAQAcAE4ATwBLAC0AQQBNAFMAUwBTAEYARQAtADAAMQAEACAAbQBnAGQAbgBvAGsALgBuAG8AawBpAGEALgBjAG8AbQADAD4AbgBvAGsALQBhAG0AcwBzAHMAZgBlAC0AMAAxAC4AbQBnAGQAbgBvAGsALgBuAG8AawBpAGEALgBjAG8AbQAFACAAbQBnAGQAbgBvAGsALgBuAG8AawBpAGEALgBjAG8AbQAAAAAA" << "NOE" << true;
|
||||
}
|
||||
|
||||
void tst_QAuthenticator::ntlmAuth()
|
||||
{
|
||||
QFETCH(QString, data);
|
||||
QFETCH(QString, realm);
|
||||
QFETCH(bool, sso);
|
||||
|
||||
QAuthenticator auth;
|
||||
if (!sso) {
|
||||
auth.setUser("unimportant");
|
||||
auth.setPassword("unimportant");
|
||||
}
|
||||
|
||||
auth.detach();
|
||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth);
|
||||
QCOMPARE(priv->phase, QAuthenticatorPrivate::Start);
|
||||
|
||||
QList<QPair<QByteArray, QByteArray> > 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"));
|
||||
priv->parseHttpResponse(headers, /*isProxy = */ false, {});
|
||||
if (sso)
|
||||
QVERIFY(priv->calculateResponse("GET", "/", u"").startsWith("NTLM "));
|
||||
else
|
||||
QCOMPARE(priv->calculateResponse("GET", "/", u"").constData(), "NTLM TlRMTVNTUAABAAAABYIIAAAAAAAAAAAAAAAAAAAAAAA=");
|
||||
|
||||
// NTLM phase 2: challenge
|
||||
headers.clear();
|
||||
headers << qMakePair(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", "/", 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);
|
||||
QList<QPair<QByteArray, QByteArray>> headers;
|
||||
// Put sha256 first, so that its parsed first...
|
||||
headers.emplace_back("WWW-Authenticate", sha256);
|
||||
headers.emplace_back("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()
|
||||
{
|
||||
QAuthenticator s1, s2;
|
||||
QVERIFY(s2 == s1);
|
||||
QVERIFY(s1 == s2);
|
||||
QVERIFY(!(s1 != s2));
|
||||
QVERIFY(!(s2 != s1));
|
||||
s1.setUser("User");
|
||||
QVERIFY(!(s2 == s1));
|
||||
QVERIFY(!(s1 == s2));
|
||||
QVERIFY(s1 != s2);
|
||||
QVERIFY(s2 != s1);
|
||||
}
|
||||
|
||||
void tst_QAuthenticator::isMethodSupported()
|
||||
{
|
||||
QVERIFY(QAuthenticatorPrivate::isMethodSupported("basic"));
|
||||
QVERIFY(QAuthenticatorPrivate::isMethodSupported("Basic realm=\"Shadow\""));
|
||||
QVERIFY(QAuthenticatorPrivate::isMethodSupported("DIgesT"));
|
||||
QVERIFY(QAuthenticatorPrivate::isMethodSupported("NTLM"));
|
||||
QVERIFY(QAuthenticatorPrivate::isMethodSupported("ntlm"));
|
||||
#if QT_CONFIG(sspi) || QT_CONFIG(gssapi)
|
||||
QVERIFY(QAuthenticatorPrivate::isMethodSupported("negotiate"));
|
||||
#else
|
||||
QVERIFY(!QAuthenticatorPrivate::isMethodSupported("negotiate"));
|
||||
#endif
|
||||
|
||||
QVERIFY(!QAuthenticatorPrivate::isMethodSupported("Bearer"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QAuthenticator);
|
||||
|
||||
#include "tst_qauthenticator.moc"
|
2
tests/auto/network/kernel/qdnslookup/BLACKLIST
Normal file
2
tests/auto/network/kernel/qdnslookup/BLACKLIST
Normal file
@ -0,0 +1,2 @@
|
||||
[lookup]
|
||||
*
|
13
tests/auto/network/kernel/qdnslookup/CMakeLists.txt
Normal file
13
tests/auto/network/kernel/qdnslookup/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qdnslookup Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qdnslookup
|
||||
SOURCES
|
||||
tst_qdnslookup.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
403
tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp
Normal file
403
tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp
Normal file
@ -0,0 +1,403 @@
|
||||
// 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 WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include <QtNetwork/QDnsLookup>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
|
||||
static const int Timeout = 15000; // 15s
|
||||
|
||||
class tst_QDnsLookup: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QString domainName(const QString &input);
|
||||
QString domainNameList(const QString &input);
|
||||
QStringList domainNameListAlternatives(const QString &input);
|
||||
public slots:
|
||||
void initTestCase();
|
||||
|
||||
private slots:
|
||||
void lookup_data();
|
||||
void lookup();
|
||||
void lookupReuse();
|
||||
void lookupAbortRetry();
|
||||
void bindingsAndProperties();
|
||||
};
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
QString tst_QDnsLookup::domainName(const QString &input)
|
||||
{
|
||||
if (input.isEmpty())
|
||||
return input;
|
||||
|
||||
if (input.endsWith(QLatin1Char('.'))) {
|
||||
QString nodot = input;
|
||||
nodot.chop(1);
|
||||
return nodot;
|
||||
}
|
||||
|
||||
QFETCH_GLOBAL(QString, tld);
|
||||
return input + tld;
|
||||
}
|
||||
|
||||
QString tst_QDnsLookup::domainNameList(const QString &input)
|
||||
{
|
||||
QStringList list = input.split(QLatin1Char(';'));
|
||||
QString result;
|
||||
foreach (const QString &s, list) {
|
||||
if (!result.isEmpty())
|
||||
result += ';';
|
||||
result += domainName(s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList tst_QDnsLookup::domainNameListAlternatives(const QString &input)
|
||||
{
|
||||
QStringList alternatives = input.split('|');
|
||||
for (int i = 0; i < alternatives.size(); ++i)
|
||||
alternatives[i] = domainNameList(alternatives[i]);
|
||||
return alternatives;
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::lookup_data()
|
||||
{
|
||||
QTest::addColumn<int>("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) << "" << "" << "" << "" << "" << "" << "";
|
||||
#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" << "" << "";
|
||||
#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();
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::lookup()
|
||||
{
|
||||
QFETCH(int, 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);
|
||||
|
||||
QDnsLookup lookup;
|
||||
lookup.setType(static_cast<QDnsLookup::Type>(type));
|
||||
lookup.setName(domain);
|
||||
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
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::lookupReuse()
|
||||
{
|
||||
QDnsLookup lookup;
|
||||
|
||||
// first lookup
|
||||
lookup.setType(QDnsLookup::A);
|
||||
lookup.setName(domainName("a-single"));
|
||||
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"));
|
||||
QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("192.0.2.1"));
|
||||
|
||||
// second lookup
|
||||
lookup.setType(QDnsLookup::AAAA);
|
||||
lookup.setName(domainName("aaaa-single"));
|
||||
lookup.lookup();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
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::lookupAbortRetry()
|
||||
{
|
||||
QDnsLookup lookup;
|
||||
|
||||
// try and abort the lookup
|
||||
lookup.setType(QDnsLookup::A);
|
||||
lookup.setName(domainName("a-single"));
|
||||
lookup.lookup();
|
||||
lookup.abort();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
QCOMPARE(int(lookup.error()), int(QDnsLookup::OperationCancelledError));
|
||||
QVERIFY(lookup.hostAddressRecords().isEmpty());
|
||||
|
||||
// retry a different lookup
|
||||
lookup.setType(QDnsLookup::AAAA);
|
||||
lookup.setName(domainName("aaaa-single"));
|
||||
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()
|
||||
{
|
||||
QFETCH_GLOBAL(const QString, tld);
|
||||
if (tld == QStringLiteral("idn"))
|
||||
return;
|
||||
|
||||
QDnsLookup lookup;
|
||||
|
||||
lookup.setType(QDnsLookup::A);
|
||||
QProperty<QDnsLookup::Type> dnsTypeProp;
|
||||
lookup.bindableType().setBinding(Qt::makePropertyBinding(dnsTypeProp));
|
||||
const QSignalSpy typeChangeSpy(&lookup, &QDnsLookup::typeChanged);
|
||||
|
||||
dnsTypeProp = QDnsLookup::AAAA;
|
||||
QCOMPARE(typeChangeSpy.size(), 1);
|
||||
QCOMPARE(lookup.type(), QDnsLookup::AAAA);
|
||||
|
||||
dnsTypeProp.setBinding(lookup.bindableType().makeBinding());
|
||||
lookup.setType(QDnsLookup::A);
|
||||
QCOMPARE(dnsTypeProp.value(), QDnsLookup::A);
|
||||
|
||||
QProperty<QString> nameProp;
|
||||
lookup.bindableName().setBinding(Qt::makePropertyBinding(nameProp));
|
||||
const QSignalSpy nameChangeSpy(&lookup, &QDnsLookup::nameChanged);
|
||||
|
||||
nameProp = QStringLiteral("a-plus-aaaa");
|
||||
QCOMPARE(nameChangeSpy.size(), 1);
|
||||
QCOMPARE(lookup.name(), QStringLiteral("a-plus-aaaa"));
|
||||
|
||||
nameProp.setBinding(lookup.bindableName().makeBinding());
|
||||
lookup.setName(QStringLiteral("a-single"));
|
||||
QCOMPARE(nameProp.value(), QStringLiteral("a-single"));
|
||||
|
||||
QProperty<QHostAddress> nameserverProp;
|
||||
lookup.bindableNameserver().setBinding(Qt::makePropertyBinding(nameserverProp));
|
||||
const QSignalSpy nameserverChangeSpy(&lookup, &QDnsLookup::nameserverChanged);
|
||||
|
||||
nameserverProp = QHostAddress::LocalHost;
|
||||
QCOMPARE(nameserverChangeSpy.size(), 1);
|
||||
QCOMPARE(lookup.nameserver(), QHostAddress::LocalHost);
|
||||
|
||||
nameserverProp.setBinding(lookup.bindableNameserver().makeBinding());
|
||||
lookup.setNameserver(QHostAddress::Any);
|
||||
QCOMPARE(nameserverProp.value(), QHostAddress::Any);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDnsLookup)
|
||||
#include "tst_qdnslookup.moc"
|
13
tests/auto/network/kernel/qdnslookup_appless/CMakeLists.txt
Normal file
13
tests/auto/network/kernel/qdnslookup_appless/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qdnslookup_appless Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qdnslookup_appless
|
||||
SOURCES
|
||||
tst_qdnslookup_appless.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtNetwork/QDnsLookup>
|
||||
#include <QTest>
|
||||
#include <QTestEventLoop>
|
||||
|
||||
class tst_QDnsLookup_Appless : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void noApplication();
|
||||
void recreateApplication();
|
||||
void destroyApplicationDuringLookup();
|
||||
};
|
||||
|
||||
void tst_QDnsLookup_Appless::noApplication()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "QDnsLookup requires a QCoreApplication");
|
||||
QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org");
|
||||
dns.lookup();
|
||||
}
|
||||
|
||||
void tst_QDnsLookup_Appless::recreateApplication()
|
||||
{
|
||||
int argc = 0;
|
||||
char **argv = 0;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
QCoreApplication app(argc, argv);
|
||||
QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org");
|
||||
dns.lookup();
|
||||
if (!dns.isFinished()) {
|
||||
QObject::connect(&dns, SIGNAL(finished()),
|
||||
&QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||
QTestEventLoop::instance().enterLoop(10);
|
||||
}
|
||||
QVERIFY(dns.isFinished());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDnsLookup_Appless::destroyApplicationDuringLookup()
|
||||
{
|
||||
int argc = 0;
|
||||
char **argv = 0;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
QCoreApplication app(argc, argv);
|
||||
QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.info");
|
||||
dns.lookup();
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QDnsLookup_Appless)
|
||||
#include "tst_qdnslookup_appless.moc"
|
21
tests/auto/network/kernel/qhostaddress/CMakeLists.txt
Normal file
21
tests/auto/network/kernel/qhostaddress/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qhostaddress Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qhostaddress
|
||||
SOURCES
|
||||
tst_qhostaddress.cpp
|
||||
LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qhostaddress CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
763
tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
Normal file
763
tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
Normal file
@ -0,0 +1,763 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <qhostaddress.h>
|
||||
#include <private/qhostaddress_p.h>
|
||||
#include <qcoreapplication.h>
|
||||
#include <QTest>
|
||||
#include <qplatformdefs.h>
|
||||
#include <qdebug.h>
|
||||
#include <qhash.h>
|
||||
#include <qbytearray.h>
|
||||
#include <qdatastream.h>
|
||||
#ifdef Q_OS_WIN
|
||||
# include <qt_windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_WASM)
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
Q_DECLARE_METATYPE(AddressClassification)
|
||||
Q_DECLARE_METATYPE(QHostAddress::SpecialAddress)
|
||||
|
||||
class tst_QHostAddress : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QHostAddress();
|
||||
|
||||
private slots:
|
||||
void constructor_QString_data();
|
||||
void constructor_QString();
|
||||
void setAddress_QString_data();
|
||||
void setAddress_QString();
|
||||
void specialAddresses_data();
|
||||
void specialAddresses();
|
||||
void compare_data();
|
||||
void compare();
|
||||
void isEqual_data();
|
||||
void isEqual();
|
||||
void assignment();
|
||||
void scopeId();
|
||||
void hashKey();
|
||||
void streaming_data();
|
||||
void streaming();
|
||||
void parseSubnet_data();
|
||||
void parseSubnet();
|
||||
void isInSubnet_data();
|
||||
void isInSubnet();
|
||||
void classification_data();
|
||||
void classification();
|
||||
void convertv4v6_data();
|
||||
void convertv4v6();
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress)
|
||||
|
||||
tst_QHostAddress::tst_QHostAddress()
|
||||
{
|
||||
qRegisterMetaType<QHostAddress>("QHostAddress");
|
||||
}
|
||||
|
||||
void tst_QHostAddress::constructor_QString_data()
|
||||
{
|
||||
setAddress_QString_data();
|
||||
}
|
||||
|
||||
void tst_QHostAddress::constructor_QString()
|
||||
{
|
||||
QFETCH(QString, address);
|
||||
QFETCH(bool, ok);
|
||||
QFETCH(int, protocol);
|
||||
|
||||
QHostAddress hostAddr(address);
|
||||
|
||||
if (address == "0.0.0.0" || address == "::") {
|
||||
QVERIFY(ok);
|
||||
} else {
|
||||
QVERIFY(hostAddr.isNull() != ok);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
QTEST(hostAddr.toString(), "resAddr");
|
||||
|
||||
if ( protocol == 4 ) {
|
||||
QVERIFY( hostAddr.protocol() == QHostAddress::IPv4Protocol || hostAddr.protocol() == QHostAddress::UnknownNetworkLayerProtocol );
|
||||
QVERIFY( hostAddr.protocol() != QHostAddress::IPv6Protocol );
|
||||
} else if ( protocol == 6 ) {
|
||||
QVERIFY( hostAddr.protocol() != QHostAddress::IPv4Protocol && hostAddr.protocol() != QHostAddress::UnknownNetworkLayerProtocol );
|
||||
QVERIFY( hostAddr.protocol() == QHostAddress::IPv6Protocol );
|
||||
} else {
|
||||
QVERIFY( hostAddr.isNull() );
|
||||
QVERIFY( hostAddr.protocol() == QHostAddress::UnknownNetworkLayerProtocol );
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHostAddress::setAddress_QString_data()
|
||||
{
|
||||
QTest::addColumn<QString>("address");
|
||||
QTest::addColumn<bool>("ok");
|
||||
QTest::addColumn<QString>("resAddr");
|
||||
QTest::addColumn<int>("protocol"); // 4: IPv4, 6: IPv6, other: undefined
|
||||
|
||||
//next we fill it with data
|
||||
QTest::newRow("ip4_00") << QString("127.0.0.1") << true << QString("127.0.0.1") << 4;
|
||||
QTest::newRow("ip4_01") << QString("255.3.2.1") << true << QString("255.3.2.1") << 4;
|
||||
QTest::newRow("ip4_03") << QString(" 255.3.2.1") << true << QString("255.3.2.1") << 4;
|
||||
QTest::newRow("ip4_04") << QString("255.3.2.1\r ") << true << QString("255.3.2.1") << 4;
|
||||
QTest::newRow("ip4_05") << QString("0.0.0.0") << true << QString("0.0.0.0") << 4;
|
||||
QTest::newRow("ip4_06") << QString("123.0.0") << true << QString("123.0.0.0") << 4;
|
||||
|
||||
// for the format of IPv6 addresses see also RFC 5952
|
||||
// rule 4.1: Leading zeros MUST be suppressed
|
||||
// rule 4.2.1: Shorten as Much as Possible
|
||||
// rule 4.2.2: The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
|
||||
// rule 4.2.3: the longest run of consecutive 16-bit 0 fields MUST be shortened
|
||||
// When the length of the consecutive 16-bit 0 fields, the first sequence
|
||||
// of zero bits MUST be shortened
|
||||
// rule 4.3: The characters "a", "b", "c", "d", "e", and "f" in an IPv6 address
|
||||
// MUST be represented in lowercase
|
||||
QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString("fedc:ba98:7654:3210:fedc:ba98:7654:3210") << 6; // 4.3
|
||||
QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; // 4.1, 4.2.1
|
||||
QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6;
|
||||
QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6;
|
||||
QTest::newRow("ip6_04") << QString("FF01::43") << true << QString("ff01::43") << 6;
|
||||
QTest::newRow("ip6_05") << QString("::1") << true << QString("::1") << 6;
|
||||
QTest::newRow("ip6_06") << QString("1::") << true << QString("1::") << 6;
|
||||
QTest::newRow("ip6_07") << QString("::") << true << QString("::") << 6;
|
||||
QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << true << QString("::13.1.68.3") << 6;
|
||||
QTest::newRow("ip6_09") << QString("::13.1.68.3") << true << QString("::13.1.68.3") << 6;
|
||||
QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6;
|
||||
QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6;
|
||||
QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << true << QString("1::ffff:8190:3426") << 6;
|
||||
QTest::newRow("ip6_13") << QString("A:B::D:E") << true << QString("a:b::d:e") << 6;
|
||||
QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << true << QString("1080:0:1:0:8:800:200c:417a") << 6; // 4.2.2
|
||||
QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << true << QString("1080:0:1:0:8:800:200c:0") << 6;
|
||||
QTest::newRow("ip6_16") << QString("1080:0:1:0:8:800:0:0") << true << QString("1080:0:1:0:8:800::") << 6;
|
||||
QTest::newRow("ip6_17a") << QString("1080:0:0:8:800:0:0:0") << true << QString("1080:0:0:8:800::") << 6; // 4.2.3a
|
||||
QTest::newRow("ip6_17b") << QString("1080:0:0:0:8:0:0:0") << true << QString("1080::8:0:0:0") << 6; // 4.2.3b
|
||||
QTest::newRow("ip6_18") << QString("0:1:1:1:8:800:0:0") << true << QString("0:1:1:1:8:800::") << 6;
|
||||
QTest::newRow("ip6_19") << QString("0:1:1:1:8:800:0:1") << true << QString("0:1:1:1:8:800:0:1") << 6;
|
||||
|
||||
QTest::newRow("error_00") << QString("foobarcom") << false << QString() << 0;
|
||||
QTest::newRow("error_01") << QString("foo.bar.com") << false << QString() << 0;
|
||||
QTest::newRow("error_02") << QString("") << false << QString() << 0;
|
||||
QTest::newRow("error_03") << QString() << false << QString() << 0;
|
||||
QTest::newRow("error_04") << QString(" \t\r") << false << QString() << 0;
|
||||
|
||||
QTest::newRow("error_ip4_00") << QString("256.9.9.9") << false << QString() << 0;
|
||||
QTest::newRow("error_ip4_01") << QString("-1.9.9.9") << false << QString() << 0;
|
||||
//QTest::newRow("error_ip4_02") << QString("123.0.0") << false << QString() << 0; // no longer invalid in Qt5
|
||||
QTest::newRow("error_ip4_02") << QString("123.0.0.") << false << QString() << 0;
|
||||
QTest::newRow("error_ip4_03") << QString("123.0.0.0.0") << false << QString() << 0;
|
||||
QTest::newRow("error_ip4_04") << QString("255.2 3.2.1") << false << QString() << 0;
|
||||
|
||||
QTest::newRow("error_ip6_00") << QString(":") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_01") << QString(":::") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_02") << QString("::AAAA:") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_03") << QString(":AAAA::") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_04") << QString("FFFF:::129.144.52.38") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_05") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210:1234") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_06") << QString("129.144.52.38::") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_07") << QString("::129.144.52.38:129.144.52.38") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_08") << QString(":::129.144.52.38") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_09") << QString("1FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_10") << QString("::FFFFFFFF") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_11") << QString("::EFGH") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_12") << QString("ABCD:ABCD:ABCD") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_13") << QString("::ABCD:ABCD::") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_14") << QString("1::2::3") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_15") << QString("1:2:::") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_16") << QString(":::1:2") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_17") << QString("1:::2") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_18") << QString("FEDC::7654:3210:FEDC:BA98::3210") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_19") << QString("ABCD:ABCD:ABCD:1.2.3.4") << false << QString() << 0;
|
||||
QTest::newRow("error_ip6_20") << QString("ABCD::ABCD::ABCD:1.2.3.4") << false << QString() << 0;
|
||||
|
||||
}
|
||||
|
||||
void tst_QHostAddress::setAddress_QString()
|
||||
{
|
||||
QFETCH(QString, address);
|
||||
QFETCH(bool, ok);
|
||||
QFETCH(int, protocol);
|
||||
|
||||
QHostAddress hostAddr;
|
||||
QCOMPARE(hostAddr.setAddress(address), ok);
|
||||
|
||||
if (ok)
|
||||
QTEST(hostAddr.toString(), "resAddr");
|
||||
|
||||
if ( protocol == 4 ) {
|
||||
QVERIFY( hostAddr.protocol() == QHostAddress::IPv4Protocol || hostAddr.protocol() == QHostAddress::UnknownNetworkLayerProtocol );
|
||||
QVERIFY( hostAddr.protocol() != QHostAddress::IPv6Protocol );
|
||||
} else if ( protocol == 6 ) {
|
||||
QVERIFY( hostAddr.protocol() != QHostAddress::IPv4Protocol && hostAddr.protocol() != QHostAddress::UnknownNetworkLayerProtocol );
|
||||
QVERIFY( hostAddr.protocol() == QHostAddress::IPv6Protocol );
|
||||
} else {
|
||||
QVERIFY( hostAddr.isNull() );
|
||||
QVERIFY( hostAddr.protocol() == QHostAddress::UnknownNetworkLayerProtocol );
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHostAddress::specialAddresses_data()
|
||||
{
|
||||
QTest::addColumn<QString>("text");
|
||||
QTest::addColumn<QHostAddress::SpecialAddress>("address");
|
||||
QTest::addColumn<bool>("result");
|
||||
|
||||
QTest::newRow("localhost_1") << QString("127.0.0.1") << QHostAddress::LocalHost << true;
|
||||
QTest::newRow("localhost_2") << QString("127.0.0.2") << QHostAddress::LocalHost << false;
|
||||
QTest::newRow("localhost_3") << QString("127.0.0.2") << QHostAddress::LocalHostIPv6 << false;
|
||||
|
||||
QTest::newRow("localhost_ipv6_4") << QString("::1") << QHostAddress::LocalHostIPv6 << true;
|
||||
QTest::newRow("localhost_ipv6_5") << QString("::2") << QHostAddress::LocalHostIPv6 << false;
|
||||
QTest::newRow("localhost_ipv6_6") << QString("::1") << QHostAddress::LocalHost << false;
|
||||
|
||||
QTest::newRow("null_1") << QString("") << QHostAddress::Null << true;
|
||||
QTest::newRow("null_2") << QString("bjarne") << QHostAddress::Null << true;
|
||||
|
||||
QTest::newRow("compare_from_null") << QString("") << QHostAddress::Broadcast << false;
|
||||
|
||||
QTest::newRow("broadcast_1") << QString("255.255.255.255") << QHostAddress::Any << false;
|
||||
QTest::newRow("broadcast_2") << QString("255.255.255.255") << QHostAddress::Broadcast << true;
|
||||
|
||||
QTest::newRow("any_ipv6") << QString("::") << QHostAddress::AnyIPv6 << true;
|
||||
QTest::newRow("any_ipv4") << QString("0.0.0.0") << QHostAddress::AnyIPv4 << true;
|
||||
|
||||
QTest::newRow("dual_not_ipv6") << QString("::") << QHostAddress::Any << false;
|
||||
QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << QHostAddress::Any << false;
|
||||
}
|
||||
|
||||
|
||||
void tst_QHostAddress::specialAddresses()
|
||||
{
|
||||
QFETCH(QString, text);
|
||||
QFETCH(QHostAddress::SpecialAddress, address);
|
||||
QFETCH(bool, result);
|
||||
QCOMPARE(QHostAddress(text) == address, result);
|
||||
|
||||
//check special address equal to itself (QTBUG-22898), note two overloads of operator==
|
||||
QVERIFY(QHostAddress(address) == QHostAddress(address));
|
||||
QVERIFY(QHostAddress(address) == address);
|
||||
QVERIFY(address == QHostAddress(address));
|
||||
QVERIFY(!(QHostAddress(address) != QHostAddress(address)));
|
||||
QVERIFY(!(QHostAddress(address) != address));
|
||||
QVERIFY(!(address != QHostAddress(address)));
|
||||
|
||||
{
|
||||
QHostAddress ha;
|
||||
ha.setAddress(address);
|
||||
QVERIFY(ha == address);
|
||||
}
|
||||
|
||||
QHostAddress setter;
|
||||
setter.setAddress(text);
|
||||
QCOMPARE(setter == address, result);
|
||||
}
|
||||
|
||||
|
||||
void tst_QHostAddress::compare_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("first");
|
||||
QTest::addColumn<QHostAddress>("second");
|
||||
QTest::addColumn<bool>("result");
|
||||
|
||||
QTest::newRow("1") << QHostAddress() << QHostAddress() << true;
|
||||
QTest::newRow("2") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::Any) << true;
|
||||
QTest::newRow("3") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6) << true;
|
||||
QTest::newRow("4") << QHostAddress(QHostAddress::Broadcast) << QHostAddress(QHostAddress::Broadcast) << true;
|
||||
QTest::newRow("5") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::Broadcast) << false;
|
||||
QTest::newRow("6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << false;
|
||||
QTest::newRow("7") << QHostAddress() << QHostAddress(QHostAddress::LocalHostIPv6) << false;
|
||||
QTest::newRow("any4-any6") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::AnyIPv6) << false;
|
||||
|
||||
Q_IPV6ADDR localhostv4mapped = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1 } };
|
||||
QTest::newRow("v4-v4mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("::ffff:127.0.0.1") << false;
|
||||
QTest::newRow("v4-v4mapped-2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(localhostv4mapped) << false;
|
||||
}
|
||||
|
||||
void tst_QHostAddress::compare()
|
||||
{
|
||||
QFETCH(QHostAddress, first);
|
||||
QFETCH(QHostAddress, second);
|
||||
QFETCH(bool, result);
|
||||
|
||||
QCOMPARE(first == second, result);
|
||||
QCOMPARE(second == first, result);
|
||||
if (result == true)
|
||||
QCOMPARE(qHash(first), qHash(second));
|
||||
}
|
||||
|
||||
void tst_QHostAddress::isEqual_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("first");
|
||||
QTest::addColumn<QHostAddress>("second");
|
||||
QTest::addColumn<int>("flags");
|
||||
QTest::addColumn<bool>("result");
|
||||
|
||||
// QHostAddress::StrictConversion is already tested in compare()
|
||||
QTest::newRow("localhost4to6-local") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertLocalHost << true;
|
||||
QTest::newRow("localhost4to6-compat") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4CompatToIPv4 << false;
|
||||
QTest::newRow("localhost4to6-mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
|
||||
QTest::newRow("localhost4to6-unspec") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << false;
|
||||
QTest::newRow("0.0.0.1-::1-local") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertLocalHost << false;
|
||||
QTest::newRow("v4-v4compat-local") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertLocalHost << false;
|
||||
QTest::newRow("v4-v4mapped-local") << QHostAddress("192.168.1.1") << QHostAddress("::ffff:192.168.1.1") << (int)QHostAddress::ConvertLocalHost << false;
|
||||
QTest::newRow("0.0.0.1-::1-unspec") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << false;
|
||||
QTest::newRow("v4-v4compat-unspec") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertUnspecifiedAddress << false;
|
||||
QTest::newRow("v4-v4mapped-unspec") << QHostAddress("192.168.1.1") << QHostAddress("::ffff:192.168.1.1") << (int)QHostAddress::ConvertUnspecifiedAddress << false;
|
||||
QTest::newRow("0.0.0.1-::1-compat") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4CompatToIPv4 << false;
|
||||
QTest::newRow("v4-v4compat-compat") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertV4CompatToIPv4 << true;
|
||||
QTest::newRow("v4-v4mapped-compat") << QHostAddress("192.168.1.1") << QHostAddress("::ffff:192.168.1.1") << (int)QHostAddress::ConvertV4CompatToIPv4 << false;
|
||||
QTest::newRow("0.0.0.1-::1-mapped") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
|
||||
QTest::newRow("v4-v4compat-mapped") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
|
||||
QTest::newRow("v4-v4mapped-mapped") << QHostAddress("192.168.1.1") << QHostAddress("::FFFF:192.168.1.1") << (int)QHostAddress::ConvertV4MappedToIPv4 << true;
|
||||
QTest::newRow("undef-any-local") << QHostAddress() << QHostAddress(QHostAddress::Any) << (int)QHostAddress::ConvertLocalHost << false;
|
||||
QTest::newRow("undef-any-unspec") << QHostAddress() << QHostAddress(QHostAddress::Any) << (int)QHostAddress::ConvertUnspecifiedAddress << false;
|
||||
QTest::newRow("anyv6-anyv4-compat") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertV4CompatToIPv4 << true;
|
||||
QTest::newRow("anyv6-anyv4-mapped") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
|
||||
QTest::newRow("anyv6-anyv4-unspec") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertUnspecifiedAddress << true;
|
||||
QTest::newRow("any-anyv4-unspec") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertUnspecifiedAddress << true;
|
||||
QTest::newRow("any-anyv6-unspec") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << true;
|
||||
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()
|
||||
{
|
||||
QFETCH(QHostAddress, first);
|
||||
QFETCH(QHostAddress, second);
|
||||
QFETCH(int, flags);
|
||||
QFETCH(bool, result);
|
||||
|
||||
QCOMPARE(first.isEqual(second, QHostAddress::ConversionModeFlag(flags)), result);
|
||||
QCOMPARE(second.isEqual(first, QHostAddress::ConversionModeFlag(flags)), result);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::assignment()
|
||||
{
|
||||
QHostAddress address;
|
||||
QHostAddress addr("4.2.2.1");
|
||||
sockaddr_in sockAddr;
|
||||
sockAddr.sin_family = AF_INET;
|
||||
sockAddr.sin_addr.s_addr = htonl(addr.toIPv4Address());
|
||||
address.setAddress((sockaddr *)&sockAddr);
|
||||
QCOMPARE(address, addr);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::scopeId()
|
||||
{
|
||||
QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0");
|
||||
QCOMPARE(address.scopeId(), QString("eth0"));
|
||||
QCOMPARE(address.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0"));
|
||||
|
||||
QHostAddress address2("fe80::2e0:4cff:fefb:662a");
|
||||
QCOMPARE(address2.scopeId(), QString());
|
||||
address2.setScopeId(QString("en0"));
|
||||
QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%en0"));
|
||||
|
||||
address2 = address;
|
||||
QCOMPARE(address2.scopeId(), QString("eth0"));
|
||||
QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0"));
|
||||
}
|
||||
|
||||
void tst_QHostAddress::hashKey()
|
||||
{
|
||||
QHash<QHostAddress, QString> hostHash;
|
||||
hostHash.insert(QHostAddress(), "ole");
|
||||
}
|
||||
|
||||
void tst_QHostAddress::streaming_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("address");
|
||||
QTest::newRow("1") << QHostAddress();
|
||||
QTest::newRow("2") << QHostAddress(0xDEADBEEF);
|
||||
QTest::newRow("3") << QHostAddress("127.128.129.130");
|
||||
QTest::newRow("4") << QHostAddress("1080:0000:0000:0000:0008:0800:200C:417A");
|
||||
QTest::newRow("5") << QHostAddress("fe80::2e0:4cff:fefb:662a%eth0");
|
||||
QTest::newRow("6") << QHostAddress(QHostAddress::Null);
|
||||
QTest::newRow("7") << QHostAddress(QHostAddress::LocalHost);
|
||||
QTest::newRow("8") << QHostAddress(QHostAddress::LocalHostIPv6);
|
||||
QTest::newRow("9") << QHostAddress(QHostAddress::Broadcast);
|
||||
QTest::newRow("10") << QHostAddress(QHostAddress::Any);
|
||||
QTest::newRow("11") << QHostAddress(QHostAddress::AnyIPv4);
|
||||
QTest::newRow("12") << QHostAddress(QHostAddress::AnyIPv6);
|
||||
QTest::newRow("13") << QHostAddress("foo.bar.com");
|
||||
}
|
||||
|
||||
void tst_QHostAddress::streaming()
|
||||
{
|
||||
QFETCH(QHostAddress, address);
|
||||
QByteArray ba;
|
||||
QDataStream ds1(&ba, QIODevice::WriteOnly);
|
||||
ds1 << address;
|
||||
QCOMPARE(ds1.status(), QDataStream::Ok);
|
||||
QDataStream ds2(&ba, QIODevice::ReadOnly);
|
||||
QHostAddress address2;
|
||||
ds2 >> address2;
|
||||
QCOMPARE(ds2.status(), QDataStream::Ok);
|
||||
QCOMPARE(address, address2);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::parseSubnet_data()
|
||||
{
|
||||
QTest::addColumn<QString>("subnet");
|
||||
QTest::addColumn<QHostAddress>("prefix");
|
||||
QTest::addColumn<int>("prefixLength");
|
||||
|
||||
// invalid/error values
|
||||
QTest::newRow("empty") << QString() << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_01") << "foobar" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_02") << " " << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_03") << "1.2.3.a" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_04") << "1.2.3.4.5" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_05") << "1.2.3.4:80" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_06") << "1.2.3.4/33" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_07") << "1.2.3.4/-1" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_08") << "1.2.3.4/256.0.0.0" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_09") << "1.2.3.4/255.253.0.0" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_10") << "1.2.3.4/255.0.0.255" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_11") << "1.2.3.4." << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_20") << "ffff::/-1" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_21") << "ffff::/129" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_22") << "ffff::/255.255.0.0" << QHostAddress() << -1;
|
||||
QTest::newRow("invalid_23") << "ffff::/ff00::" << QHostAddress() << -1;
|
||||
|
||||
// correct IPv4 with netmask
|
||||
QTest::newRow("netmask_0") << "0.0.0.0/0.0.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 0;
|
||||
QTest::newRow("netmask_1") << "0.0.0.0/255.128.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 9;
|
||||
QTest::newRow("netmask_2") << "0.0.0.0/255.192.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 10;
|
||||
QTest::newRow("netmask_3") << "0.0.0.0/255.224.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 11;
|
||||
QTest::newRow("netmask_4") << "0.0.0.0/255.240.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 12;
|
||||
QTest::newRow("netmask_5") << "0.0.0.0/255.248.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 13;
|
||||
QTest::newRow("netmask_6") << "0.0.0.0/255.252.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 14;
|
||||
QTest::newRow("netmask_7") << "0.0.0.0/255.254.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 15;
|
||||
QTest::newRow("netmask_8") << "0.0.0.0/255.255.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 16;
|
||||
QTest::newRow("netmask_16") << "0.0.0.0/255.255.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 16;
|
||||
QTest::newRow("netmask_24") << "0.0.0.0/255.255.255.0" << QHostAddress(QHostAddress::AnyIPv4) << 24;
|
||||
QTest::newRow("netmask_31") << "0.0.0.0/255.255.255.254" << QHostAddress(QHostAddress::AnyIPv4) << 31;
|
||||
QTest::newRow("netmask_32") << "0.0.0.0/255.255.255.255" << QHostAddress(QHostAddress::AnyIPv4) << 32;
|
||||
|
||||
// correct IPv4 with prefix
|
||||
QTest::newRow("prefix_0") << "0.0.0.0/0" << QHostAddress(QHostAddress::AnyIPv4) << 0;
|
||||
QTest::newRow("prefix_1") << "0.0.0.0/1" << QHostAddress(QHostAddress::AnyIPv4) << 1;
|
||||
QTest::newRow("prefix_9") << "0.0.0.0/9" << QHostAddress(QHostAddress::AnyIPv4) << 9;
|
||||
QTest::newRow("prefix_31") << "0.0.0.0/31" << QHostAddress(QHostAddress::AnyIPv4) << 31;
|
||||
QTest::newRow("prefix_32") << "0.0.0.0/32" << QHostAddress(QHostAddress::AnyIPv4) << 32;
|
||||
|
||||
// correct IPv4 without prefix or netmask
|
||||
QTest::newRow("classA") << "10" << QHostAddress("10.0.0.0") << 8;
|
||||
QTest::newRow("classA+dot") << "10." << QHostAddress("10.0.0.0") << 8;
|
||||
QTest::newRow("classB") << "172.16" << QHostAddress("172.16.0.0") << 16;
|
||||
QTest::newRow("classB+dot") << "172.16." << QHostAddress("172.16.0.0") << 16;
|
||||
QTest::newRow("classC") << "192.168.0" << QHostAddress("192.168.0.0") << 24;
|
||||
QTest::newRow("classC+dot") << "192.168.0" << QHostAddress("192.168.0.0") << 24;
|
||||
QTest::newRow("full-ipv4") << "192.168.0.1" << QHostAddress("192.168.0.1") << 32;
|
||||
|
||||
// correct IPv6 with prefix
|
||||
QTest::newRow("ipv6_01") << "::/0" << QHostAddress(QHostAddress::AnyIPv6) << 0;
|
||||
QTest::newRow("ipv6_03") << "::/3" << QHostAddress(QHostAddress::AnyIPv6) << 3;
|
||||
QTest::newRow("ipv6_16") << "::/16" << QHostAddress(QHostAddress::AnyIPv6) << 16;
|
||||
QTest::newRow("ipv6_48") << "::/48" << QHostAddress(QHostAddress::AnyIPv6) << 48;
|
||||
QTest::newRow("ipv6_127") << "::/127" << QHostAddress(QHostAddress::AnyIPv6) << 127;
|
||||
QTest::newRow("ipv6_128") << "::/128" << QHostAddress(QHostAddress::AnyIPv6) << 128;
|
||||
|
||||
// tail bit clearing:
|
||||
QTest::newRow("clear_01") << "255.255.255.255/31" << QHostAddress("255.255.255.254") << 31;
|
||||
QTest::newRow("clear_08") << "255.255.255.255/24" << QHostAddress("255.255.255.0") << 24;
|
||||
QTest::newRow("clear_09") << "255.255.255.255/23" << QHostAddress("255.255.254.0") << 23;
|
||||
QTest::newRow("clear_10") << "255.255.255.255/22" << QHostAddress("255.255.252.0") << 22;
|
||||
QTest::newRow("clear_11") << "255.255.255.255/21" << QHostAddress("255.255.248.0") << 21;
|
||||
QTest::newRow("clear_12") << "255.255.255.255/20" << QHostAddress("255.255.240.0") << 20;
|
||||
QTest::newRow("clear_13") << "255.255.255.255/19" << QHostAddress("255.255.224.0") << 19;
|
||||
QTest::newRow("clear_14") << "255.255.255.255/18" << QHostAddress("255.255.192.0") << 18;
|
||||
QTest::newRow("clear_15") << "255.255.255.255/17" << QHostAddress("255.255.128.0") << 17;
|
||||
QTest::newRow("clear_16") << "255.255.255.255/16" << QHostAddress("255.255.0.0") << 16;
|
||||
QTest::newRow("clear_24") << "255.255.255.255/8" << QHostAddress("255.0.0.0") << 8;
|
||||
QTest::newRow("clear_31") << "255.255.255.255/1" << QHostAddress("128.0.0.0") << 1;
|
||||
QTest::newRow("clear_32") << "255.255.255.255/0" << QHostAddress("0.0.0.0") << 0;
|
||||
|
||||
// same for IPv6:
|
||||
QTest::newRow("ipv6_clear_01") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/127"
|
||||
<< QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe")
|
||||
<< 127;
|
||||
QTest::newRow("ipv6_clear_07") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/121"
|
||||
<< QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80")
|
||||
<< 121;
|
||||
QTest::newRow("ipv6_clear_08") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/120"
|
||||
<< QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00")
|
||||
<< 120;
|
||||
QTest::newRow("ipv6_clear_16") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/112"
|
||||
<< QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0")
|
||||
<< 112;
|
||||
QTest::newRow("ipv6_clear_80") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/48"
|
||||
<< QHostAddress("ffff:ffff:ffff::")
|
||||
<< 48;
|
||||
QTest::newRow("ipv6_clear_81") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/47"
|
||||
<< QHostAddress("ffff:ffff:fffe::")
|
||||
<< 47;
|
||||
QTest::newRow("ipv6_clear_82") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/46"
|
||||
<< QHostAddress("ffff:ffff:fffc::")
|
||||
<< 46;
|
||||
QTest::newRow("ipv6_clear_83") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/45"
|
||||
<< QHostAddress("ffff:ffff:fff8::")
|
||||
<< 45;
|
||||
QTest::newRow("ipv6_clear_84") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/44"
|
||||
<< QHostAddress("ffff:ffff:fff0::")
|
||||
<< 44;
|
||||
QTest::newRow("ipv6_clear_85") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/43"
|
||||
<< QHostAddress("ffff:ffff:ffe0::")
|
||||
<< 43;
|
||||
QTest::newRow("ipv6_clear_86") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/42"
|
||||
<< QHostAddress("ffff:ffff:ffc0::")
|
||||
<< 42;
|
||||
QTest::newRow("ipv6_clear_87") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/41"
|
||||
<< QHostAddress("ffff:ffff:ff80::")
|
||||
<< 41;
|
||||
QTest::newRow("ipv6_clear_88") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/40"
|
||||
<< QHostAddress("ffff:ffff:ff00::")
|
||||
<< 40;
|
||||
QTest::newRow("ipv6_clear_125") << "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/3"
|
||||
<< QHostAddress("2000::")
|
||||
<< 3;
|
||||
QTest::newRow("ipv6_clear_127") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/1"
|
||||
<< QHostAddress("8000::")
|
||||
<< 1;
|
||||
QTest::newRow("ipv6_clear_128") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0"
|
||||
<< QHostAddress(QHostAddress::AnyIPv6)
|
||||
<< 0;
|
||||
}
|
||||
|
||||
void tst_QHostAddress::parseSubnet()
|
||||
{
|
||||
QFETCH(QString, subnet);
|
||||
QFETCH(QHostAddress, prefix);
|
||||
QFETCH(int, prefixLength);
|
||||
|
||||
QPair<QHostAddress, int> result = QHostAddress::parseSubnet(subnet);
|
||||
QCOMPARE(result.first, prefix);
|
||||
QCOMPARE(result.second, prefixLength);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::isInSubnet_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("address");
|
||||
QTest::addColumn<QHostAddress>("prefix");
|
||||
QTest::addColumn<int>("prefixLength");
|
||||
QTest::addColumn<bool>("result");
|
||||
|
||||
// invalid QHostAddresses are never in any subnets
|
||||
QTest::newRow("invalid_01") << QHostAddress() << QHostAddress() << 32 << false;
|
||||
QTest::newRow("invalid_02") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 32 << false;
|
||||
QTest::newRow("invalid_03") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 8 << false;
|
||||
QTest::newRow("invalid_04") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 0 << false;
|
||||
QTest::newRow("invalid_05") << QHostAddress() << QHostAddress("255.255.255.0") << 24 << false;
|
||||
QTest::newRow("invalid_06") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 0 << false;
|
||||
QTest::newRow("invalid_07") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 32 << false;
|
||||
QTest::newRow("invalid_08") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 128<< false;
|
||||
|
||||
// and no host address can be in a subnet whose prefix is invalid
|
||||
QTest::newRow("invalid_20") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress() << 16 << false;
|
||||
QTest::newRow("invalid_21") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress() << 16 << false;
|
||||
QTest::newRow("invalid_22") << QHostAddress(QHostAddress::LocalHost) << QHostAddress() << 16 << false;
|
||||
QTest::newRow("invalid_23") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress() << 16 << false;
|
||||
|
||||
// negative netmasks don't make sense:
|
||||
QTest::newRow("invalid_30") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::Any) << -1 << false;
|
||||
QTest::newRow("invalid_31") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6) << -1 << false;
|
||||
|
||||
// we don't support IPv4 belonging in an IPv6 netmask and vice-versa
|
||||
QTest::newRow("v4-in-v6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv6) << 0 << false;
|
||||
QTest::newRow("v6-in-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::Any) << 0 << false;
|
||||
QTest::newRow("v4-in-v6mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:255.0.0.0") << 113 << false;
|
||||
QTest::newRow("v4-in-v6mapped2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("::ffff:255.0.0.0") << 113 << false;
|
||||
|
||||
// IPv4 correct ones
|
||||
QTest::newRow("netmask_0") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << 0 << true;
|
||||
QTest::newRow("netmask_0bis") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("255.255.0.0") << 0 << true;
|
||||
QTest::newRow("netmask_0ter") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("1.2.3.4") << 0 << true;
|
||||
QTest::newRow("netmask_1") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << 1 << true;
|
||||
QTest::newRow("~netmask_1") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("128.0.0.0") << 1 << false;
|
||||
QTest::newRow("netmask_1bis") << QHostAddress("224.0.0.1") << QHostAddress("128.0.0.0") << 1 << true;
|
||||
QTest::newRow("~netmask_1bis") << QHostAddress("224.0.0.1") << QHostAddress("0.0.0.0") << 1 << false;
|
||||
QTest::newRow("netmask_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("127.0.0.0") << 8 << true;
|
||||
QTest::newRow("~netmask_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("126.0.0.0") << 8 << false;
|
||||
QTest::newRow("netmask_15") << QHostAddress("10.0.1.255") << QHostAddress("10.0.0.0") << 15 << true;
|
||||
QTest::newRow("netmask_16") << QHostAddress("172.16.0.1") << QHostAddress("172.16.0.0") << 16 << true;
|
||||
|
||||
// the address is always in the subnet containing its address, regardless of length:
|
||||
QTest::newRow("same_01") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 1 << true;
|
||||
QTest::newRow("same_07") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 7 << true;
|
||||
QTest::newRow("same_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 8 << true;
|
||||
QTest::newRow("same_24") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 23 << true;
|
||||
QTest::newRow("same_31") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 31 << true;
|
||||
QTest::newRow("same_32") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 32 << true;
|
||||
|
||||
// IPv6 correct ones:
|
||||
QTest::newRow("ipv6_netmask_0") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << 0 << true;
|
||||
QTest::newRow("ipv6_netmask_0bis") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::LocalHostIPv6) << 0 << true;
|
||||
QTest::newRow("ipv6_netmask_0ter") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress("ffff::") << 0 << true;
|
||||
QTest::newRow("ipv6_netmask_1") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << 1 << true;
|
||||
QTest::newRow("ipv6_netmask_1bis") << QHostAddress("fec0::1") << QHostAddress("8000::") << 1 << true;
|
||||
QTest::newRow("~ipv6_netmask_1") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress("8000::") << 1 << false;
|
||||
QTest::newRow("~ipv6_netmask_1bis") << QHostAddress("fec0::1") << QHostAddress("::") << 1 << false;
|
||||
QTest::newRow("ipv6_netmask_47") << QHostAddress("2:3:5::1") << QHostAddress("2:3:4::") << 47 << true;
|
||||
QTest::newRow("ipv6_netmask_48") << QHostAddress("2:3:4::1") << QHostAddress("2:3:4::") << 48 << true;
|
||||
QTest::newRow("~ipv6_netmask_48") << QHostAddress("2:3:5::1") << QHostAddress("2:3:4::") << 48 << false;
|
||||
QTest::newRow("ipv6_netmask_127") << QHostAddress("2:3:4:5::1") << QHostAddress("2:3:4:5::") << 127 << true;
|
||||
QTest::newRow("ipv6_netmask_128") << QHostAddress("2:3:4:5::1") << QHostAddress("2:3:4:5::1") << 128 << true;
|
||||
QTest::newRow("~ipv6_netmask_128") << QHostAddress("2:3:4:5::1") << QHostAddress("2:3:4:5::0") << 128 << false;
|
||||
}
|
||||
|
||||
void tst_QHostAddress::isInSubnet()
|
||||
{
|
||||
QFETCH(QHostAddress, address);
|
||||
QFETCH(QHostAddress, prefix);
|
||||
QFETCH(int, prefixLength);
|
||||
|
||||
QTEST(address.isInSubnet(prefix, prefixLength), "result");
|
||||
}
|
||||
|
||||
void tst_QHostAddress::classification_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("address");
|
||||
QTest::addColumn<AddressClassification>("result");
|
||||
|
||||
QTest::newRow("default") << QHostAddress() << UnknownAddress;
|
||||
QTest::newRow("invalid") << QHostAddress("&&&") << UnknownAddress;
|
||||
|
||||
QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << LocalNetAddress;
|
||||
QTest::newRow("Null") << QHostAddress(QHostAddress::Null) << UnknownAddress;
|
||||
|
||||
// IPv6 address space
|
||||
auto addV6 = [](const char *str, AddressClassification cl) {
|
||||
QTest::newRow(str) << QHostAddress(str) << cl;
|
||||
};
|
||||
QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << LocalNetAddress;
|
||||
QTest::newRow("ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << LoopbackAddress;
|
||||
addV6("::", LocalNetAddress);
|
||||
addV6("::1", LoopbackAddress);
|
||||
addV6("::2", GlobalAddress);
|
||||
addV6("2000::", GlobalAddress);
|
||||
addV6("3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress);
|
||||
addV6("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress);
|
||||
addV6("fc00::", UniqueLocalAddress);
|
||||
addV6("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UniqueLocalAddress);
|
||||
addV6("fe00::", UnknownAddress);
|
||||
addV6("fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UnknownAddress);
|
||||
addV6("fe80::", LinkLocalAddress);
|
||||
addV6("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", LinkLocalAddress);
|
||||
addV6("fec0::", SiteLocalAddress);
|
||||
addV6("feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", SiteLocalAddress);
|
||||
addV6("ff00::", MulticastAddress);
|
||||
addV6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", MulticastAddress);
|
||||
|
||||
// IPv4 address space
|
||||
auto addV4 = [](const char *str, AddressClassification cl) {
|
||||
QTest::newRow(str) << QHostAddress(str) << cl;
|
||||
QByteArray v6 = "::ffff:";
|
||||
v6 += str;
|
||||
QTest::newRow(v6.constData()) << QHostAddress(QString::fromLatin1(v6)) << cl;
|
||||
};
|
||||
QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << LocalNetAddress;
|
||||
QTest::newRow("ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << LoopbackAddress;
|
||||
QTest::newRow("Broadcast") << QHostAddress(QHostAddress::Broadcast) << BroadcastAddress;
|
||||
addV4("0.0.0.0", LocalNetAddress);
|
||||
addV4("0.0.0.1", LocalNetAddress);
|
||||
addV4("0.255.255.255", LocalNetAddress);
|
||||
addV4("1.0.0.0", GlobalAddress);
|
||||
addV4("1.2.3.4", GlobalAddress);
|
||||
addV4("10.0.0.4", PrivateNetworkAddress);
|
||||
addV4("127.0.0.1", LoopbackAddress);
|
||||
addV4("127.0.0.2", LoopbackAddress);
|
||||
addV4("127.255.255.255", LoopbackAddress);
|
||||
addV4("192.168.3.4", PrivateNetworkAddress);
|
||||
addV4("223.255.255.255", GlobalAddress);
|
||||
addV4("224.0.0.0", MulticastAddress);
|
||||
addV4("239.255.255.255", MulticastAddress);
|
||||
addV4("240.0.0.0", UnknownAddress);
|
||||
addV4("255.255.255.254", UnknownAddress);
|
||||
addV4("255.255.255.255", BroadcastAddress);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::classification()
|
||||
{
|
||||
QFETCH(QHostAddress, address);
|
||||
QFETCH(AddressClassification, result);
|
||||
|
||||
bool isLoopback = (result == LoopbackAddress);
|
||||
bool isGlobal = (result & GlobalAddress); // GlobalAddress is a bit
|
||||
bool isLinkLocal = (result == LinkLocalAddress);
|
||||
bool isSiteLocal = (result == SiteLocalAddress);
|
||||
bool isUniqueLocalAddress = (result == UniqueLocalAddress);
|
||||
bool isMulticast = (result == MulticastAddress);
|
||||
bool isBroadcast = (result == BroadcastAddress);
|
||||
|
||||
QCOMPARE(address.isLoopback(), isLoopback);
|
||||
QCOMPARE(address.isGlobal(), isGlobal);
|
||||
QCOMPARE(address.isLinkLocal(), isLinkLocal);
|
||||
QCOMPARE(address.isSiteLocal(), isSiteLocal);
|
||||
QCOMPARE(address.isUniqueLocalUnicast(), isUniqueLocalAddress);
|
||||
QCOMPARE(address.isMulticast(), isMulticast);
|
||||
QCOMPARE(address.isBroadcast(), isBroadcast);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::convertv4v6_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("source");
|
||||
QTest::addColumn<int>("protocol");
|
||||
QTest::addColumn<QHostAddress>("result");
|
||||
|
||||
QTest::newRow("any-to-v4") << QHostAddress(QHostAddress::Any) << 4 << QHostAddress(QHostAddress::AnyIPv4);
|
||||
QTest::newRow("any-to-v6") << QHostAddress(QHostAddress::Any) << 6 << QHostAddress(QHostAddress::AnyIPv6);
|
||||
QTest::newRow("anyv4-to-v6") << QHostAddress(QHostAddress::AnyIPv4) << 6 << QHostAddress(QHostAddress::AnyIPv6);
|
||||
QTest::newRow("anyv6-to-v4") << QHostAddress(QHostAddress::AnyIPv6) << 4 << QHostAddress(QHostAddress::AnyIPv4);
|
||||
|
||||
QTest::newRow("v4mapped-to-v4") << QHostAddress("::ffff:192.0.2.1") << 4 << QHostAddress("192.0.2.1");
|
||||
QTest::newRow("v4-to-v4mapped") << QHostAddress("192.0.2.1") << 6 << QHostAddress("::ffff:192.0.2.1");
|
||||
|
||||
// we won't convert 127.0.0.1 to ::1 or vice-versa:
|
||||
// you can connect to a v4 server socket with ::ffff:127.0.0.1, but not with ::1
|
||||
QTest::newRow("localhost-to-v4mapped") << QHostAddress(QHostAddress::LocalHost) << 6 << QHostAddress("::ffff:127.0.0.1");
|
||||
QTest::newRow("v4mapped-to-localhost") << QHostAddress("::ffff:127.0.0.1") << 4 << QHostAddress(QHostAddress::LocalHost);
|
||||
|
||||
// in turn, that means localhost6 doesn't convert to v4
|
||||
QTest::newRow("localhost6-to-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << 4 << QHostAddress();
|
||||
|
||||
// some other v6 addresses that won't convert to v4
|
||||
QTest::newRow("v4compat-to-v4") << QHostAddress("::192.0.2.1") << 4 << QHostAddress();
|
||||
QTest::newRow("localhostv4compat-to-v4") << QHostAddress("::127.0.0.1") << 4 << QHostAddress();
|
||||
QTest::newRow("v6global-to-v4") << QHostAddress("2001:db8::1") << 4 << QHostAddress();
|
||||
QTest::newRow("v6multicast-to-v4") << QHostAddress("ff02::1") << 4 << QHostAddress();
|
||||
}
|
||||
|
||||
void tst_QHostAddress::convertv4v6()
|
||||
{
|
||||
QFETCH(QHostAddress, source);
|
||||
QFETCH(int, protocol);
|
||||
QFETCH(QHostAddress, result);
|
||||
|
||||
if (protocol == 4) {
|
||||
bool ok;
|
||||
quint32 v4 = source.toIPv4Address(&ok);
|
||||
QCOMPARE(ok, result.protocol() == QHostAddress::IPv4Protocol);
|
||||
if (ok)
|
||||
QCOMPARE(QHostAddress(v4), result);
|
||||
} else if (protocol == 6) {
|
||||
QCOMPARE(QHostAddress(source.toIPv6Address()), result);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHostAddress)
|
||||
#include "tst_qhostaddress.moc"
|
6
tests/auto/network/kernel/qhostinfo/BLACKLIST
Normal file
6
tests/auto/network/kernel/qhostinfo/BLACKLIST
Normal file
@ -0,0 +1,6 @@
|
||||
# These tests fail due to a DNS server issue
|
||||
# (this is not a Qt bug)
|
||||
[lookupIPv6:a-plus-aaaa]
|
||||
windows ci
|
||||
[blockingLookup:a-plus-aaaa]
|
||||
windows ci
|
26
tests/auto/network/kernel/qhostinfo/CMakeLists.txt
Normal file
26
tests/auto/network/kernel/qhostinfo/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
## tst_qhostinfo Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qhostinfo
|
||||
SOURCES
|
||||
tst_qhostinfo.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::NetworkPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qhostinfo CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
713
tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
Normal file
713
tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
Normal file
@ -0,0 +1,713 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
// 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 <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QTcpSocket>
|
||||
#include <QTcpServer>
|
||||
|
||||
#include <private/qthread_p.h>
|
||||
|
||||
#include <time.h>
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <qt_windows.h>
|
||||
#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>
|
||||
#endif
|
||||
|
||||
#include "../../../network-settings.h"
|
||||
|
||||
#define TEST_DOMAIN ".test.qt-project.org"
|
||||
|
||||
|
||||
class tst_QHostInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
void initTestCase();
|
||||
void swapFunction();
|
||||
void moveOperator();
|
||||
void getSetCheck();
|
||||
void staticInformation();
|
||||
void lookupIPv4_data();
|
||||
void lookupIPv4();
|
||||
void lookupIPv6_data();
|
||||
void lookupIPv6();
|
||||
void lookupConnectToFunctionPointer_data();
|
||||
void lookupConnectToFunctionPointer();
|
||||
void lookupConnectToFunctionPointerDeleted();
|
||||
void lookupConnectToLambda_data();
|
||||
void lookupConnectToLambda();
|
||||
void reverseLookup_data();
|
||||
void reverseLookup();
|
||||
|
||||
void blockingLookup_data();
|
||||
void blockingLookup();
|
||||
|
||||
void raceCondition();
|
||||
void threadSafety();
|
||||
void threadSafetyAsynchronousAPI();
|
||||
|
||||
void multipleSameLookups();
|
||||
void multipleDifferentLookups_data();
|
||||
void multipleDifferentLookups();
|
||||
|
||||
void cache();
|
||||
|
||||
void abortHostLookup();
|
||||
protected slots:
|
||||
void resultsReady(const QHostInfo &);
|
||||
|
||||
private:
|
||||
bool ipv6LookupsAvailable;
|
||||
bool ipv6Available;
|
||||
bool lookupDone;
|
||||
int lookupsDoneCounter;
|
||||
QHostInfo lookupResults;
|
||||
};
|
||||
|
||||
void tst_QHostInfo::swapFunction()
|
||||
{
|
||||
QHostInfo obj1, obj2;
|
||||
obj1.setError(QHostInfo::HostInfoError(0));
|
||||
obj2.setError(QHostInfo::HostInfoError(1));
|
||||
obj1.swap(obj2);
|
||||
QCOMPARE(QHostInfo::HostInfoError(0), obj2.error());
|
||||
QCOMPARE(QHostInfo::HostInfoError(1), obj1.error());
|
||||
}
|
||||
|
||||
void tst_QHostInfo::moveOperator()
|
||||
{
|
||||
QHostInfo obj1, obj2, obj3(1);
|
||||
obj1.setError(QHostInfo::HostInfoError(0));
|
||||
obj2.setError(QHostInfo::HostInfoError(1));
|
||||
obj1 = std::move(obj2);
|
||||
obj2 = obj3;
|
||||
QCOMPARE(QHostInfo::HostInfoError(1), obj1.error());
|
||||
QCOMPARE(obj3.lookupId(), obj2.lookupId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QHostInfo::getSetCheck()
|
||||
{
|
||||
QHostInfo obj1;
|
||||
// HostInfoError QHostInfo::error()
|
||||
// void QHostInfo::setError(HostInfoError)
|
||||
obj1.setError(QHostInfo::HostInfoError(0));
|
||||
QCOMPARE(QHostInfo::HostInfoError(0), obj1.error());
|
||||
obj1.setError(QHostInfo::HostInfoError(1));
|
||||
QCOMPARE(QHostInfo::HostInfoError(1), obj1.error());
|
||||
|
||||
// int QHostInfo::lookupId()
|
||||
// void QHostInfo::setLookupId(int)
|
||||
obj1.setLookupId(0);
|
||||
QCOMPARE(0, obj1.lookupId());
|
||||
obj1.setLookupId(INT_MIN);
|
||||
QCOMPARE(INT_MIN, obj1.lookupId());
|
||||
obj1.setLookupId(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.lookupId());
|
||||
}
|
||||
|
||||
void tst_QHostInfo::staticInformation()
|
||||
{
|
||||
qDebug() << "Hostname:" << QHostInfo::localHostName();
|
||||
qDebug() << "Domain name:" << QHostInfo::localDomainName();
|
||||
}
|
||||
|
||||
void tst_QHostInfo::initTestCase()
|
||||
{
|
||||
ipv6Available = false;
|
||||
ipv6LookupsAvailable = false;
|
||||
|
||||
QTcpServer server;
|
||||
if (server.listen(QHostAddress("::1"))) {
|
||||
// We have IPv6 support
|
||||
ipv6Available = true;
|
||||
}
|
||||
|
||||
// check if the system getaddrinfo can do IPv6 lookups
|
||||
struct addrinfo hint, *result = 0;
|
||||
memset(&hint, 0, sizeof hint);
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
#ifdef AI_ADDRCONFIG
|
||||
hint.ai_flags = AI_ADDRCONFIG;
|
||||
#endif
|
||||
|
||||
int res = getaddrinfo("::1", "80", &hint, &result);
|
||||
if (res == 0) {
|
||||
// this test worked
|
||||
freeaddrinfo(result);
|
||||
res = getaddrinfo("aaaa-single" TEST_DOMAIN, "80", &hint, &result);
|
||||
if (res == 0 && result != 0 && result->ai_family != AF_INET) {
|
||||
freeaddrinfo(result);
|
||||
ipv6LookupsAvailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
// run each testcase with and without test enabled
|
||||
QTest::addColumn<bool>("cache");
|
||||
QTest::newRow("WithCache") << true;
|
||||
QTest::newRow("WithoutCache") << false;
|
||||
}
|
||||
|
||||
void tst_QHostInfo::init()
|
||||
{
|
||||
// delete the cache so inidividual testcase results are independent from each other
|
||||
qt_qhostinfo_clear_cache();
|
||||
|
||||
QFETCH_GLOBAL(bool, cache);
|
||||
qt_qhostinfo_enable_cache(cache);
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupIPv4_data()
|
||||
{
|
||||
QTest::addColumn<QString>("hostname");
|
||||
QTest::addColumn<QString>("addresses");
|
||||
QTest::addColumn<int>("err");
|
||||
|
||||
QTest::newRow("empty") << "" << "" << int(QHostInfo::HostNotFound);
|
||||
|
||||
QTest::newRow("single_ip4") << "a-single" TEST_DOMAIN << "192.0.2.1" << int(QHostInfo::NoError);
|
||||
QTest::newRow("multiple_ip4") << "a-multi" TEST_DOMAIN << "192.0.2.1 192.0.2.2 192.0.2.3" << int(QHostInfo::NoError);
|
||||
QTest::newRow("literal_ip4") << "192.0.2.1" << "192.0.2.1" << int(QHostInfo::NoError);
|
||||
|
||||
QTest::newRow("notfound") << "invalid" TEST_DOMAIN << "" << int(QHostInfo::HostNotFound);
|
||||
|
||||
QTest::newRow("idn-ace") << "a-single.xn--alqualond-34a" TEST_DOMAIN << "192.0.2.1" << int(QHostInfo::NoError);
|
||||
QTest::newRow("idn-unicode") << QString::fromLatin1("a-single.alqualond\353" TEST_DOMAIN) << "192.0.2.1" << int(QHostInfo::NoError);
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupIPv4()
|
||||
{
|
||||
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);
|
||||
|
||||
QStringList tmp;
|
||||
for (int i = 0; i < lookupResults.addresses().size(); ++i)
|
||||
tmp.append(lookupResults.addresses().at(i).toString());
|
||||
tmp.sort();
|
||||
|
||||
QStringList expected = addresses.split(' ');
|
||||
expected.sort();
|
||||
|
||||
QCOMPARE(tmp.join(' '), expected.join(' '));
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupIPv6_data()
|
||||
{
|
||||
QTest::addColumn<QString>("hostname");
|
||||
QTest::addColumn<QString>("addresses");
|
||||
QTest::addColumn<int>("err");
|
||||
|
||||
QTest::newRow("aaaa-single") << "aaaa-single" TEST_DOMAIN << "2001:db8::1" << int(QHostInfo::NoError);
|
||||
QTest::newRow("aaaa-multi") << "aaaa-multi" TEST_DOMAIN << "2001:db8::1 2001:db8::2 2001:db8::3" << int(QHostInfo::NoError);
|
||||
QTest::newRow("a-plus-aaaa") << "a-plus-aaaa" TEST_DOMAIN << "198.51.100.1 2001:db8::1:1" << int(QHostInfo::NoError);
|
||||
|
||||
// avoid using real IPv6 addresses here because this will do a DNS query
|
||||
// real addresses are between 2000:: and 3fff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
QTest::newRow("literal_ip6") << "f001:6b0:1:ea:202:a5ff:fecd:13a6" << "f001:6b0:1:ea:202:a5ff:fecd:13a6" << int(QHostInfo::NoError);
|
||||
QTest::newRow("literal_shortip6") << "f001:618:1401::4" << "f001:618:1401::4" << int(QHostInfo::NoError);
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupIPv6()
|
||||
{
|
||||
QFETCH(QString, hostname);
|
||||
QFETCH(int, err);
|
||||
QFETCH(QString, addresses);
|
||||
|
||||
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().size(); ++i)
|
||||
tmp.append(lookupResults.addresses().at(i).toString());
|
||||
tmp.sort();
|
||||
|
||||
QStringList expected = addresses.split(' ');
|
||||
expected.sort();
|
||||
|
||||
QCOMPARE(tmp.join(' ').toLower(), expected.join(' ').toLower());
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupConnectToFunctionPointer_data()
|
||||
{
|
||||
lookupIPv4_data();
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupConnectToFunctionPointer()
|
||||
{
|
||||
QFETCH(QString, hostname);
|
||||
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(' '));
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupConnectToFunctionPointerDeleted()
|
||||
{
|
||||
{
|
||||
QObject contextObject;
|
||||
QHostInfo::lookupHost("localhost", &contextObject, [](const QHostInfo){
|
||||
QFAIL("This should never be called!");
|
||||
});
|
||||
}
|
||||
QTestEventLoop::instance().enterLoop(3);
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupConnectToLambda_data()
|
||||
{
|
||||
lookupIPv4_data();
|
||||
}
|
||||
|
||||
void tst_QHostInfo::lookupConnectToLambda()
|
||||
{
|
||||
QFETCH(QString, hostname);
|
||||
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().size(); ++i)
|
||||
tmp.append(lookupResults.addresses().at(i).toString());
|
||||
tmp.sort();
|
||||
|
||||
QStringList expected = addresses.split(' ');
|
||||
expected.sort();
|
||||
|
||||
QCOMPARE(tmp.join(' '), expected.join(' '));
|
||||
}
|
||||
|
||||
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";
|
||||
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.size()).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.size()).trimmed();
|
||||
if (address == ip.toUtf8()) {
|
||||
results << name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
qDebug() << "Failure to parse nslookup output: " << lines;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
void tst_QHostInfo::reverseLookup_data()
|
||||
{
|
||||
QTest::addColumn<QString>("address");
|
||||
QTest::addColumn<QStringList>("hostNames");
|
||||
QTest::addColumn<int>("err");
|
||||
QTest::addColumn<bool>("ipv6");
|
||||
|
||||
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;
|
||||
QTest::newRow("bogus-name IPv6") << QString("1::2::3::4") << QStringList() << 1 << true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (err == 0) {
|
||||
if (!hostNames.contains(info.hostName()))
|
||||
qDebug() << "Failure: expecting" << hostNames << ",got " << info.hostName();
|
||||
QVERIFY(hostNames.contains(info.hostName()));
|
||||
QCOMPARE(info.addresses().first(), QHostAddress(address));
|
||||
} else {
|
||||
QCOMPARE(info.hostName(), address);
|
||||
QCOMPARE(info.error(), QHostInfo::HostNotFound);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void tst_QHostInfo::blockingLookup_data()
|
||||
{
|
||||
lookupIPv4_data();
|
||||
if (ipv6LookupsAvailable)
|
||||
lookupIPv6_data();
|
||||
}
|
||||
|
||||
void tst_QHostInfo::blockingLookup()
|
||||
{
|
||||
QFETCH(QString, hostname);
|
||||
QFETCH(int, err);
|
||||
QFETCH(QString, addresses);
|
||||
|
||||
QHostInfo hostInfo = QHostInfo::fromName(hostname);
|
||||
QStringList tmp;
|
||||
for (int i = 0; i < hostInfo.addresses().size(); ++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());
|
||||
}
|
||||
|
||||
void tst_QHostInfo::raceCondition()
|
||||
{
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost("invalid" TEST_DOMAIN, 80);
|
||||
}
|
||||
}
|
||||
|
||||
class LookupThread : public QThread
|
||||
{
|
||||
protected:
|
||||
inline void run() override
|
||||
{
|
||||
QHostInfo info = QHostInfo::fromName("a-single" TEST_DOMAIN);
|
||||
QCOMPARE(info.error(), QHostInfo::NoError);
|
||||
QVERIFY(info.addresses().size() > 0);
|
||||
QCOMPARE(info.addresses().at(0).toString(), QString("192.0.2.1"));
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QHostInfo::threadSafety()
|
||||
{
|
||||
const int nattempts = 5;
|
||||
const int runs = 100;
|
||||
LookupThread thr[nattempts];
|
||||
for (int j = 0; j < runs; ++j) {
|
||||
for (int i = 0; i < nattempts; ++i)
|
||||
thr[i].start();
|
||||
for (int k = nattempts - 1; k >= 0; --k)
|
||||
thr[k].wait();
|
||||
}
|
||||
}
|
||||
|
||||
class LookupReceiver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void start();
|
||||
void resultsReady(const QHostInfo&);
|
||||
public:
|
||||
QHostInfo result;
|
||||
int numrequests;
|
||||
};
|
||||
|
||||
void LookupReceiver::start()
|
||||
{
|
||||
for (int i=0;i<numrequests;i++)
|
||||
QHostInfo::lookupHost(QString("a-single" TEST_DOMAIN), this, SLOT(resultsReady(QHostInfo)));
|
||||
}
|
||||
|
||||
void LookupReceiver::resultsReady(const QHostInfo &info)
|
||||
{
|
||||
result = info;
|
||||
numrequests--;
|
||||
if (numrequests == 0 || info.error() != QHostInfo::NoError)
|
||||
QThread::currentThread()->quit();
|
||||
}
|
||||
|
||||
void tst_QHostInfo::threadSafetyAsynchronousAPI()
|
||||
{
|
||||
const int nattempts = 10;
|
||||
const int lookupsperthread = 10;
|
||||
QList<QThread*> threads;
|
||||
QList<LookupReceiver*> receivers;
|
||||
for (int i = 0; i < nattempts; ++i) {
|
||||
QThread* thread = new QThread;
|
||||
LookupReceiver* receiver = new LookupReceiver;
|
||||
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.size() - 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);
|
||||
}
|
||||
}
|
||||
|
||||
// this test is for the multi-threaded QHostInfo rewrite. It is about getting results at all,
|
||||
// not about getting correct IPs
|
||||
void tst_QHostInfo::multipleSameLookups()
|
||||
{
|
||||
const int COUNT = 10;
|
||||
lookupsDoneCounter = 0;
|
||||
|
||||
for (int i = 0; i < COUNT; i++)
|
||||
QHostInfo::lookupHost("localhost", this, SLOT(resultsReady(QHostInfo)));
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
while (timer.elapsed() < 10000 && lookupsDoneCounter < COUNT) {
|
||||
QTestEventLoop::instance().enterLoop(2);
|
||||
}
|
||||
QCOMPARE(lookupsDoneCounter, COUNT);
|
||||
}
|
||||
|
||||
// this test is for the multi-threaded QHostInfo rewrite. It is about getting results at all,
|
||||
// not about getting correct IPs
|
||||
void tst_QHostInfo::multipleDifferentLookups_data()
|
||||
{
|
||||
QTest::addColumn<int>("repeats");
|
||||
QTest::newRow("1") << 1;
|
||||
QTest::newRow("2") << 2;
|
||||
QTest::newRow("5") << 5;
|
||||
QTest::newRow("10") << 10;
|
||||
}
|
||||
|
||||
void tst_QHostInfo::multipleDifferentLookups()
|
||||
{
|
||||
QStringList hostnameList;
|
||||
hostnameList << "a-single" TEST_DOMAIN
|
||||
<< "a-multi" TEST_DOMAIN
|
||||
<< "aaaa-single" TEST_DOMAIN
|
||||
<< "aaaa-multi" TEST_DOMAIN
|
||||
<< "a-plus-aaaa" TEST_DOMAIN
|
||||
<< "multi" TEST_DOMAIN
|
||||
<< "localhost" TEST_DOMAIN
|
||||
<< "cname" TEST_DOMAIN
|
||||
<< "127.0.0.1" << "----";
|
||||
|
||||
QFETCH(int, repeats);
|
||||
const int COUNT = hostnameList.size();
|
||||
lookupsDoneCounter = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void tst_QHostInfo::cache()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, cache);
|
||||
if (!cache)
|
||||
return; // test makes only sense when cache enabled
|
||||
|
||||
// reset slot counter
|
||||
lookupsDoneCounter = 0;
|
||||
|
||||
// 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);
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
QVERIFY(!valid);
|
||||
QVERIFY(result.addresses().isEmpty());
|
||||
|
||||
// loopkup second time, result should come directly
|
||||
valid = false;
|
||||
result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id);
|
||||
QVERIFY(valid);
|
||||
QVERIFY(!result.addresses().isEmpty());
|
||||
|
||||
// clear the cache
|
||||
qt_qhostinfo_clear_cache();
|
||||
|
||||
// lookup third time, result should not come directly.
|
||||
valid = true;
|
||||
result = qt_qhostinfo_lookup("localhost", this, 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);
|
||||
}
|
||||
|
||||
void tst_QHostInfo::resultsReady(const QHostInfo &hi)
|
||||
{
|
||||
QVERIFY(QThread::currentThread() == thread());
|
||||
lookupDone = true;
|
||||
lookupResults = hi;
|
||||
lookupsDoneCounter++;
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
void tst_QHostInfo::abortHostLookup()
|
||||
{
|
||||
//reset counter
|
||||
lookupsDoneCounter = 0;
|
||||
bool valid = false;
|
||||
int id = -1;
|
||||
QHostInfo result = qt_qhostinfo_lookup("a-single" TEST_DOMAIN, this, 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);
|
||||
}
|
||||
|
||||
class LookupAborter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void abort()
|
||||
{
|
||||
QHostInfo::abortHostLookup(id);
|
||||
QThread::currentThread()->quit();
|
||||
}
|
||||
public:
|
||||
int id;
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_QHostInfo)
|
||||
#include "tst_qhostinfo.moc"
|
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qnetworkaddressentry Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qnetworkaddressentry
|
||||
SOURCES
|
||||
tst_qnetworkaddressentry.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
@ -0,0 +1,146 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qnetworkinterface.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress)
|
||||
|
||||
class tst_QNetworkAddressEntry: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void getSetCheck();
|
||||
void prefixAndNetmask_data();
|
||||
void prefixAndNetmask();
|
||||
};
|
||||
|
||||
void tst_QNetworkAddressEntry::getSetCheck()
|
||||
{
|
||||
QNetworkAddressEntry entry;
|
||||
|
||||
QVERIFY(entry.ip().isNull());
|
||||
QVERIFY(entry.netmask().isNull());
|
||||
QVERIFY(entry.broadcast().isNull());
|
||||
QCOMPARE(entry.prefixLength(), -1);
|
||||
|
||||
entry.setIp(QHostAddress::LocalHost);
|
||||
QCOMPARE(entry.ip(), QHostAddress(QHostAddress::LocalHost));
|
||||
entry.setIp(QHostAddress());
|
||||
QVERIFY(entry.ip().isNull());
|
||||
|
||||
entry.setBroadcast(QHostAddress::LocalHost);
|
||||
QCOMPARE(entry.broadcast(), QHostAddress(QHostAddress::LocalHost));
|
||||
entry.setBroadcast(QHostAddress());
|
||||
QVERIFY(entry.broadcast().isNull());
|
||||
|
||||
// netmask and prefix length tested in the next test
|
||||
entry.setIp(QHostAddress::LocalHost);
|
||||
entry.setBroadcast(QHostAddress::LocalHost);
|
||||
|
||||
QNetworkAddressEntry entry2;
|
||||
QVERIFY(entry != entry2);
|
||||
QVERIFY(!(entry == entry2));
|
||||
|
||||
entry = entry2;
|
||||
QCOMPARE(entry, entry2);
|
||||
QCOMPARE(entry, entry);
|
||||
QVERIFY(!(entry != entry2));
|
||||
}
|
||||
|
||||
void tst_QNetworkAddressEntry::prefixAndNetmask_data()
|
||||
{
|
||||
QTest::addColumn<QHostAddress>("ip");
|
||||
QTest::addColumn<QHostAddress>("netmask");
|
||||
QTest::addColumn<int>("prefix");
|
||||
|
||||
// IPv4 set:
|
||||
QHostAddress ipv4(QHostAddress::LocalHost);
|
||||
QTest::newRow("v4/0") << ipv4 << QHostAddress(QHostAddress::AnyIPv4) << 0;
|
||||
QTest::newRow("v4/32") << ipv4 << QHostAddress("255.255.255.255") << 32;
|
||||
QTest::newRow("v4/24") << ipv4 << QHostAddress("255.255.255.0") << 24;
|
||||
QTest::newRow("v4/23") << ipv4 << QHostAddress("255.255.254.0") << 23;
|
||||
QTest::newRow("v4/20") << ipv4 << QHostAddress("255.255.240.0") << 20;
|
||||
QTest::newRow("v4/invalid1") << ipv4 << QHostAddress(QHostAddress::LocalHost) << -1;
|
||||
QTest::newRow("v4/invalid2") << ipv4 << QHostAddress(QHostAddress::AnyIPv6) << -1;
|
||||
QTest::newRow("v4/invalid3") << ipv4 << QHostAddress("255.255.253.0") << -1;
|
||||
QTest::newRow("v4/invalid4") << ipv4 << QHostAddress() << -2;
|
||||
QTest::newRow("v4/invalid5") << ipv4 << QHostAddress() << 33;
|
||||
|
||||
// IPv6 set:
|
||||
QHostAddress ipv6(QHostAddress::LocalHostIPv6);
|
||||
QTest::newRow("v6/0") << ipv6 << QHostAddress(QHostAddress::AnyIPv6) << 0;
|
||||
QTest::newRow("v6/128") << ipv6 << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") << 128;
|
||||
QTest::newRow("v6/64") << ipv6 << QHostAddress("ffff:ffff:ffff:ffff::") << 64;
|
||||
QTest::newRow("v6/63") << ipv6 << QHostAddress("ffff:ffff:ffff:fffe::") << 63;
|
||||
QTest::newRow("v6/60") << ipv6 << QHostAddress("ffff:ffff:ffff:fff0::") << 60;
|
||||
QTest::newRow("v6/48") << ipv6 << QHostAddress("ffff:ffff:ffff::") << 48;
|
||||
QTest::newRow("v6/3") << ipv6 << QHostAddress("e000::") << 3;
|
||||
QTest::newRow("v6/invalid1") << ipv6 << QHostAddress(QHostAddress::LocalHostIPv6) << -1;
|
||||
QTest::newRow("v6/invalid2") << ipv6 << QHostAddress(QHostAddress::Any) << -1;
|
||||
QTest::newRow("v6/invalid3") << ipv6 << QHostAddress("fffd::") << -1;
|
||||
QTest::newRow("v6/invalid4") << ipv6 << QHostAddress() << -2;
|
||||
QTest::newRow("v6/invalid5") << ipv6 << QHostAddress() << 129;
|
||||
}
|
||||
|
||||
void tst_QNetworkAddressEntry::prefixAndNetmask()
|
||||
{
|
||||
QFETCH(QHostAddress, ip);
|
||||
QFETCH(QHostAddress, netmask);
|
||||
QFETCH(int, prefix);
|
||||
|
||||
QNetworkAddressEntry entry;
|
||||
|
||||
// first, without setting the IP, all must be invalid:
|
||||
entry.setNetmask(netmask);
|
||||
QVERIFY(entry.netmask().isNull());
|
||||
entry.setPrefixLength(prefix);
|
||||
QCOMPARE(entry.prefixLength(), -1);
|
||||
|
||||
// set the IP:
|
||||
entry.setIp(ip);
|
||||
|
||||
// set the netmask:
|
||||
if (!netmask.isNull()) {
|
||||
entry.setNetmask(netmask);
|
||||
|
||||
// was it a valid one?
|
||||
if (prefix != -1) {
|
||||
QVERIFY(!entry.netmask().isNull());
|
||||
QCOMPARE(entry.netmask(), netmask);
|
||||
QCOMPARE(entry.prefixLength(), prefix);
|
||||
} else {
|
||||
// not valid
|
||||
QVERIFY(entry.netmask().isNull());
|
||||
QCOMPARE(entry.prefixLength(), -1);
|
||||
}
|
||||
}
|
||||
entry.setNetmask(QHostAddress());
|
||||
QVERIFY(entry.netmask().isNull());
|
||||
QCOMPARE(entry.prefixLength(), -1);
|
||||
|
||||
// set the prefix
|
||||
if (prefix != -1) {
|
||||
entry.setPrefixLength(prefix);
|
||||
|
||||
// was it a valid one?
|
||||
if (!netmask.isNull()) {
|
||||
QVERIFY(!entry.netmask().isNull());
|
||||
QCOMPARE(entry.netmask(), netmask);
|
||||
QCOMPARE(entry.prefixLength(), prefix);
|
||||
} else {
|
||||
// not valid
|
||||
QVERIFY(entry.netmask().isNull());
|
||||
QCOMPARE(entry.prefixLength(), -1);
|
||||
}
|
||||
}
|
||||
entry.setPrefixLength(-1);
|
||||
QVERIFY(entry.netmask().isNull());
|
||||
QCOMPARE(entry.prefixLength(), -1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNetworkAddressEntry)
|
||||
#include "tst_qnetworkaddressentry.moc"
|
||||
|
13
tests/auto/network/kernel/qnetworkdatagram/CMakeLists.txt
Normal file
13
tests/auto/network/kernel/qnetworkdatagram/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qnetworkdatagram Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qnetworkdatagram
|
||||
SOURCES
|
||||
tst_qnetworkdatagram.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
@ -0,0 +1,132 @@
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QNetworkDatagram>
|
||||
#include <QTest>
|
||||
#include <QCoreApplication>
|
||||
|
||||
class tst_QNetworkDatagram : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QNetworkDatagram();
|
||||
|
||||
private Q_SLOTS:
|
||||
void getSetCheck();
|
||||
void makeReply_data();
|
||||
void makeReply();
|
||||
};
|
||||
|
||||
tst_QNetworkDatagram::tst_QNetworkDatagram()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QNetworkDatagram::getSetCheck()
|
||||
{
|
||||
QNetworkDatagram dg;
|
||||
|
||||
QVERIFY(dg.isNull());
|
||||
QVERIFY(!dg.isValid());
|
||||
QCOMPARE(dg.senderAddress(), QHostAddress());
|
||||
QCOMPARE(dg.destinationAddress(), QHostAddress());
|
||||
QCOMPARE(dg.senderPort(), -1);
|
||||
QCOMPARE(dg.destinationPort(), -1);
|
||||
QCOMPARE(dg.hopLimit(), -1);
|
||||
QCOMPARE(dg.interfaceIndex(), 0U);
|
||||
|
||||
dg.setHopLimit(1);
|
||||
QCOMPARE(dg.hopLimit(), 1);
|
||||
dg.setHopLimit(255);
|
||||
QCOMPARE(dg.hopLimit(), 255);
|
||||
|
||||
dg.setInterfaceIndex(1);
|
||||
QCOMPARE(dg.interfaceIndex(), 1U);
|
||||
dg.setInterfaceIndex(1234567U);
|
||||
QCOMPARE(dg.interfaceIndex(), 1234567U);
|
||||
|
||||
dg.setSender(QHostAddress::Any, 12345);
|
||||
QCOMPARE(dg.senderAddress(), QHostAddress(QHostAddress::Any));
|
||||
QCOMPARE(dg.senderPort(), 12345);
|
||||
dg.setSender(QHostAddress::LocalHost);
|
||||
QCOMPARE(dg.senderAddress(), QHostAddress(QHostAddress::LocalHost));
|
||||
QCOMPARE(dg.senderPort(), 0);
|
||||
|
||||
dg.setDestination(QHostAddress::LocalHostIPv6, 12345);
|
||||
QCOMPARE(dg.destinationAddress(), QHostAddress(QHostAddress::LocalHostIPv6));
|
||||
QCOMPARE(dg.destinationPort(), 12345);
|
||||
dg.setDestination(QHostAddress::Broadcast, 137);
|
||||
QCOMPARE(dg.destinationAddress(), QHostAddress(QHostAddress::Broadcast));
|
||||
QCOMPARE(dg.destinationPort(), 137);
|
||||
|
||||
auto dg2 = dg;
|
||||
QCOMPARE(dg2.hopLimit(), dg.hopLimit());
|
||||
QCOMPARE(dg2.interfaceIndex(), dg.interfaceIndex());
|
||||
QCOMPARE(dg2.senderAddress(), dg.senderAddress());
|
||||
QCOMPARE(dg2.senderPort(), dg.senderPort());
|
||||
QCOMPARE(dg2.destinationAddress(), dg.destinationAddress());
|
||||
QCOMPARE(dg2.destinationPort(), dg.destinationPort());
|
||||
|
||||
dg.clear();
|
||||
QVERIFY(dg.isNull());
|
||||
}
|
||||
|
||||
void tst_QNetworkDatagram::makeReply_data()
|
||||
{
|
||||
qRegisterMetaType<QNetworkDatagram>();
|
||||
QTest::addColumn<QNetworkDatagram>("dgram");
|
||||
QTest::addColumn<QString>("localAddress");
|
||||
|
||||
QNetworkDatagram dgram("some data", QHostAddress("192.0.2.1"), 10001);
|
||||
dgram.setHopLimit(64);
|
||||
dgram.setSender(QHostAddress::LocalHost, 12345);
|
||||
QTest::newRow("ipv4") << dgram << "192.0.2.1";
|
||||
|
||||
dgram.setDestination(QHostAddress("224.0.0.1"), 10002);
|
||||
QTest::newRow("ipv4-multicast") << dgram << QString();
|
||||
|
||||
dgram.setSender(QHostAddress::LocalHostIPv6, 12346);
|
||||
dgram.setDestination(QHostAddress("2001:db8::1"), 12347);
|
||||
QTest::newRow("ipv6") << dgram << "2001:db8::1";
|
||||
|
||||
dgram.setSender(QHostAddress("fe80::1%1"), 10003);
|
||||
dgram.setDestination(QHostAddress("fe80::2%1"), 10004);
|
||||
dgram.setInterfaceIndex(1);
|
||||
QTest::newRow("ipv6-linklocal") << dgram << "fe80::2%1";
|
||||
|
||||
dgram.setDestination(QHostAddress("ff02::1%1"), 10005);
|
||||
QTest::newRow("ipv6-multicast") << dgram << QString();
|
||||
}
|
||||
|
||||
void tst_QNetworkDatagram::makeReply()
|
||||
{
|
||||
QFETCH(QNetworkDatagram, dgram);
|
||||
QFETCH(QString, localAddress);
|
||||
|
||||
{
|
||||
QNetworkDatagram reply = dgram.makeReply("World");
|
||||
QCOMPARE(reply.data(), QByteArray("World"));
|
||||
QCOMPARE(reply.senderAddress(), QHostAddress(localAddress));
|
||||
QCOMPARE(reply.senderPort(), localAddress.isEmpty() ? -1 : dgram.destinationPort());
|
||||
QCOMPARE(reply.destinationAddress(), dgram.senderAddress());
|
||||
QCOMPARE(reply.destinationPort(), dgram.senderPort());
|
||||
QCOMPARE(reply.interfaceIndex(), dgram.interfaceIndex());
|
||||
QCOMPARE(reply.hopLimit(), -1);
|
||||
}
|
||||
|
||||
QNetworkDatagram copy = dgram;
|
||||
copy.setData(copy.data());
|
||||
{
|
||||
QNetworkDatagram reply = std::move(copy).makeReply("World");
|
||||
QCOMPARE(reply.data(), QByteArray("World"));
|
||||
QCOMPARE(reply.senderAddress(), QHostAddress(localAddress));
|
||||
QCOMPARE(reply.senderPort(), localAddress.isEmpty() ? -1 : dgram.destinationPort());
|
||||
QCOMPARE(reply.destinationAddress(), dgram.senderAddress());
|
||||
QCOMPARE(reply.destinationPort(), dgram.senderPort());
|
||||
QCOMPARE(reply.interfaceIndex(), dgram.interfaceIndex());
|
||||
QCOMPARE(reply.hopLimit(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNetworkDatagram)
|
||||
#include "tst_qnetworkdatagram.moc"
|
@ -0,0 +1,9 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_test(tst_qnetworkinformation
|
||||
SOURCES
|
||||
tst_qnetworkinformation.cpp
|
||||
LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
@ -0,0 +1,255 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtNetwork/private/qnetworkinformation_p.h>
|
||||
#include <QtNetwork/qnetworkinformation.h>
|
||||
#include <QtTest/qtest.h>
|
||||
#include <QtTest/qsignalspy.h>
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
class MockFactory;
|
||||
class tst_QNetworkInformation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void supportedFeatures();
|
||||
void reachability();
|
||||
void behindCaptivePortal();
|
||||
void transportMedium();
|
||||
void isMetered();
|
||||
void cleanupTestCase();
|
||||
|
||||
private:
|
||||
std::unique_ptr<MockFactory> mockFactory;
|
||||
};
|
||||
|
||||
static const QString mockName = QStringLiteral("mock");
|
||||
class MockBackend : public QNetworkInformationBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MockBackend()
|
||||
{
|
||||
Q_ASSERT(!instance);
|
||||
instance = this;
|
||||
setReachability(QNetworkInformation::Reachability::Online);
|
||||
setNewBehindCaptivePortal(false);
|
||||
}
|
||||
~MockBackend() { instance = nullptr; }
|
||||
|
||||
QString name() const override { return mockName; }
|
||||
|
||||
QNetworkInformation::Features featuresSupported() const override
|
||||
{
|
||||
return featuresSupportedStatic();
|
||||
}
|
||||
|
||||
static void setNewReachability(QNetworkInformation::Reachability value)
|
||||
{
|
||||
Q_ASSERT(instance);
|
||||
instance->setReachability(value);
|
||||
}
|
||||
|
||||
static void setNewBehindCaptivePortal(bool value)
|
||||
{
|
||||
Q_ASSERT(instance);
|
||||
instance->setBehindCaptivePortal(value);
|
||||
}
|
||||
|
||||
static void setNewTransportMedium(QNetworkInformation::TransportMedium medium)
|
||||
{
|
||||
Q_ASSERT(instance);
|
||||
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::Metered };
|
||||
}
|
||||
|
||||
private:
|
||||
static inline MockBackend *instance = nullptr;
|
||||
};
|
||||
|
||||
class MockFactory : public QNetworkInformationBackendFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QString name() const override { return mockName; }
|
||||
QNetworkInformationBackend *
|
||||
create(QNetworkInformation::Features requiredFeatures) const override
|
||||
{
|
||||
if ((requiredFeatures & featuresSupported()) != requiredFeatures)
|
||||
return nullptr;
|
||||
return new MockBackend();
|
||||
}
|
||||
QNetworkInformation::Features featuresSupported() const override
|
||||
{
|
||||
return MockBackend::featuresSupportedStatic();
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QNetworkInformation::initTestCase()
|
||||
{
|
||||
auto prevBackends = QNetworkInformation::availableBackends();
|
||||
qDebug() << "available backends:" << prevBackends;
|
||||
// Creating the factory registers it as a backend
|
||||
mockFactory = std::make_unique<MockFactory>();
|
||||
auto backends = QNetworkInformation::availableBackends();
|
||||
QVERIFY(backends.size() > prevBackends.size());
|
||||
QVERIFY(backends.contains(u"mock"));
|
||||
QVERIFY(QNetworkInformation::loadBackendByName(u"mock"));
|
||||
QVERIFY(QNetworkInformation::loadBackendByName(u"mock"));
|
||||
QVERIFY(QNetworkInformation::loadBackendByName(u"mOcK"));
|
||||
QVERIFY(!QNetworkInformation::loadBackendByName(u"mocks"));
|
||||
}
|
||||
|
||||
void tst_QNetworkInformation::cleanupTestCase()
|
||||
{
|
||||
// Make sure the factory gets unregistered on destruction:
|
||||
mockFactory.reset();
|
||||
auto backends = QNetworkInformation::availableBackends();
|
||||
QVERIFY(!backends.contains(u"mock"));
|
||||
}
|
||||
|
||||
void tst_QNetworkInformation::supportedFeatures()
|
||||
{
|
||||
auto info = QNetworkInformation::instance();
|
||||
|
||||
auto allFeatures = QNetworkInformation::Features(QNetworkInformation::Feature::CaptivePortal
|
||||
| QNetworkInformation::Feature::Reachability
|
||||
| QNetworkInformation::Feature::TransportMedium
|
||||
| QNetworkInformation::Feature::Metered);
|
||||
|
||||
QCOMPARE(info->supportedFeatures(), allFeatures);
|
||||
|
||||
QVERIFY(info->supports(allFeatures));
|
||||
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()
|
||||
{
|
||||
auto info = QNetworkInformation::instance();
|
||||
QNetworkInformation::Reachability boundIsOnline = QNetworkInformation::Reachability::Unknown;
|
||||
bool signalEmitted = false;
|
||||
|
||||
connect(info, &QNetworkInformation::reachabilityChanged, this, [&, info]() {
|
||||
signalEmitted = true;
|
||||
boundIsOnline = info->reachability();
|
||||
});
|
||||
QCOMPARE(info->reachability(), QNetworkInformation::Reachability::Online);
|
||||
MockBackend::setNewReachability(QNetworkInformation::Reachability::Disconnected);
|
||||
QCoreApplication::processEvents();
|
||||
QVERIFY(signalEmitted);
|
||||
QCOMPARE(info->reachability(), QNetworkInformation::Reachability::Disconnected);
|
||||
QCOMPARE(boundIsOnline, QNetworkInformation::Reachability::Disconnected);
|
||||
|
||||
// Set the same value again, signal should not be emitted again
|
||||
signalEmitted = false;
|
||||
MockBackend::setNewReachability(QNetworkInformation::Reachability::Disconnected);
|
||||
QCoreApplication::processEvents();
|
||||
QVERIFY(!signalEmitted);
|
||||
|
||||
MockBackend::setNewReachability(QNetworkInformation::Reachability::Local);
|
||||
QCOMPARE(info->reachability(), QNetworkInformation::Reachability::Local);
|
||||
QCOMPARE(boundIsOnline, QNetworkInformation::Reachability::Local);
|
||||
MockBackend::setNewReachability(QNetworkInformation::Reachability::Site);
|
||||
QCOMPARE(info->reachability(), QNetworkInformation::Reachability::Site);
|
||||
QCOMPARE(boundIsOnline, QNetworkInformation::Reachability::Site);
|
||||
}
|
||||
|
||||
void tst_QNetworkInformation::behindCaptivePortal()
|
||||
{
|
||||
auto info = QNetworkInformation::instance();
|
||||
bool behindPortal = false;
|
||||
bool signalEmitted = false;
|
||||
|
||||
connect(info, &QNetworkInformation::isBehindCaptivePortalChanged, this,
|
||||
[&, info](bool state) {
|
||||
signalEmitted = true;
|
||||
QCOMPARE(state, info->isBehindCaptivePortal());
|
||||
behindPortal = info->isBehindCaptivePortal();
|
||||
});
|
||||
QVERIFY(!info->isBehindCaptivePortal());
|
||||
MockBackend::setNewBehindCaptivePortal(true);
|
||||
QCoreApplication::processEvents();
|
||||
QVERIFY(signalEmitted);
|
||||
QVERIFY(info->isBehindCaptivePortal());
|
||||
QVERIFY(behindPortal);
|
||||
|
||||
// Set the same value again, signal should not be emitted again
|
||||
signalEmitted = false;
|
||||
MockBackend::setNewBehindCaptivePortal(true);
|
||||
QCoreApplication::processEvents();
|
||||
QVERIFY(!signalEmitted);
|
||||
}
|
||||
|
||||
void tst_QNetworkInformation::transportMedium()
|
||||
{
|
||||
auto info = QNetworkInformation::instance();
|
||||
using TransportMedium = QNetworkInformation::TransportMedium;
|
||||
TransportMedium medium = TransportMedium::Unknown;
|
||||
bool signalEmitted = false;
|
||||
|
||||
connect(info, &QNetworkInformation::transportMediumChanged, this, [&, info](TransportMedium tm) {
|
||||
signalEmitted = true;
|
||||
QCOMPARE(tm, info->transportMedium());
|
||||
medium = info->transportMedium();
|
||||
});
|
||||
QCOMPARE(info->transportMedium(), TransportMedium::Unknown); // Default is unknown
|
||||
|
||||
auto transportMediumEnum = QMetaEnum::fromType<TransportMedium>();
|
||||
auto mediumCount = transportMediumEnum.keyCount();
|
||||
// Verify index 0 is Unknown and skip it in the loop, it's the default.
|
||||
QCOMPARE(TransportMedium(transportMediumEnum.value(0)), TransportMedium::Unknown);
|
||||
for (int i = 1; i < mediumCount; ++i) {
|
||||
signalEmitted = false;
|
||||
TransportMedium m = TransportMedium(transportMediumEnum.value(i));
|
||||
MockBackend::setNewTransportMedium(m);
|
||||
QCoreApplication::processEvents();
|
||||
QVERIFY(signalEmitted);
|
||||
QCOMPARE(info->transportMedium(), m);
|
||||
QCOMPARE(medium, m);
|
||||
}
|
||||
|
||||
// Set the current value again, signal should not be emitted again
|
||||
signalEmitted = false;
|
||||
MockBackend::setNewTransportMedium(medium);
|
||||
QCoreApplication::processEvents();
|
||||
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"
|
@ -0,0 +1,9 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_test(tst_qnetworkinformation_appless
|
||||
SOURCES
|
||||
tst_qnetworkinformation_appless.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtNetwork/qnetworkinformation.h>
|
||||
#include <QtTest/qtest.h>
|
||||
|
||||
class tst_QNetworkInformation_appless : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void reinit();
|
||||
};
|
||||
|
||||
void tst_QNetworkInformation_appless::reinit()
|
||||
{
|
||||
int argc = 1;
|
||||
char name[] = "./test";
|
||||
char *argv[] = { name, nullptr };
|
||||
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
if (QNetworkInformation::availableBackends().isEmpty())
|
||||
QSKIP("No backends available!");
|
||||
|
||||
QVERIFY(QNetworkInformation::loadDefaultBackend());
|
||||
auto info = QNetworkInformation::instance();
|
||||
QVERIFY(info);
|
||||
}
|
||||
|
||||
QVERIFY(!QNetworkInformation::instance());
|
||||
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QVERIFY(QNetworkInformation::loadDefaultBackend());
|
||||
auto info = QNetworkInformation::instance();
|
||||
QVERIFY(info);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QNetworkInformation_appless);
|
||||
#include "tst_qnetworkinformation_appless.moc"
|
14
tests/auto/network/kernel/qnetworkinterface/CMakeLists.txt
Normal file
14
tests/auto/network/kernel/qnetworkinterface/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qnetworkinterface Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qnetworkinterface
|
||||
SOURCES
|
||||
tst_qnetworkinterface.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
QT_TEST_SERVER_LIST "apache2"
|
||||
)
|
@ -0,0 +1,303 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QtEndian>
|
||||
#include <QSet>
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
#include <qnetworkinterface.h>
|
||||
#include <qudpsocket.h>
|
||||
#include "../../../network-settings.h"
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress)
|
||||
|
||||
class tst_QNetworkInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QNetworkInterface();
|
||||
virtual ~tst_QNetworkInterface();
|
||||
|
||||
bool isIPv6Working();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void dump();
|
||||
void consistencyCheck();
|
||||
void loopbackIPv4();
|
||||
void loopbackIPv6();
|
||||
void localAddress_data();
|
||||
void localAddress();
|
||||
void interfaceFromXXX_data();
|
||||
void interfaceFromXXX();
|
||||
void copyInvalidInterface();
|
||||
private:
|
||||
bool hasNetworkServer = false;
|
||||
};
|
||||
|
||||
tst_QNetworkInterface::tst_QNetworkInterface()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QNetworkInterface::~tst_QNetworkInterface()
|
||||
{
|
||||
}
|
||||
|
||||
bool tst_QNetworkInterface::isIPv6Working()
|
||||
{
|
||||
// Version without following cannot get IPV6 information
|
||||
#if !defined(QT_NO_GETIFADDRS) && !defined(QT_NO_IPV6IFNAME)
|
||||
QUdpSocket socket;
|
||||
socket.connectToHost(QHostAddress::LocalHostIPv6, 1234);
|
||||
return socket.state() == QAbstractSocket::ConnectedState || socket.waitForConnected(100);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::initTestCase()
|
||||
{
|
||||
#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) {
|
||||
QString flags;
|
||||
if (i.flags() & QNetworkInterface::IsUp) flags += "Up,";
|
||||
if (i.flags() & QNetworkInterface::IsRunning) flags += "Running,";
|
||||
if (i.flags() & QNetworkInterface::CanBroadcast) flags += "Broadcast,";
|
||||
if (i.flags() & QNetworkInterface::IsLoopBack) flags += "Loopback,";
|
||||
if (i.flags() & QNetworkInterface::IsPointToPoint) flags += "PointToPoint,";
|
||||
if (i.flags() & QNetworkInterface::CanMulticast) flags += "Multicast,";
|
||||
flags.chop(1); // drop last comma
|
||||
|
||||
QString friendlyName = i.humanReadableName();
|
||||
if (friendlyName != i.name()) {
|
||||
friendlyName.prepend('(');
|
||||
friendlyName.append(')');
|
||||
} else {
|
||||
friendlyName.clear();
|
||||
}
|
||||
qDebug() << "Interface: " << i.name() << qPrintable(friendlyName);
|
||||
QVERIFY(i.isValid());
|
||||
|
||||
qDebug() << " index: " << i.index();
|
||||
qDebug() << " flags: " << qPrintable(flags);
|
||||
qDebug() << " type: " << i.type();
|
||||
qDebug() << " hw address:" << qPrintable(i.hardwareAddress());
|
||||
qDebug() << " MTU: " << i.maximumTransmissionUnit();
|
||||
|
||||
int count = 0;
|
||||
foreach (const QNetworkAddressEntry &e, i.addressEntries()) {
|
||||
QDebug s = qDebug();
|
||||
s.nospace() << " address "
|
||||
<< qSetFieldWidth(2) << count++ << qSetFieldWidth(0);
|
||||
s.nospace() << ": " << qPrintable(e.ip().toString());
|
||||
if (!e.netmask().isNull())
|
||||
s.nospace() << '/' << e.prefixLength()
|
||||
<< " (" << qPrintable(e.netmask().toString()) << ')';
|
||||
if (!e.broadcast().isNull())
|
||||
s.nospace() << " broadcast " << qPrintable(e.broadcast().toString());
|
||||
if (e.dnsEligibility() == QNetworkAddressEntry::DnsEligible)
|
||||
s.nospace() << " dns-eligible";
|
||||
else if (e.dnsEligibility() == QNetworkAddressEntry::DnsIneligible)
|
||||
s.nospace() << " dns-ineligible";
|
||||
if (e.isLifetimeKnown()) {
|
||||
#define printable(l) qPrintable(l.isForever() ? "forever" : QString::fromLatin1("%1ms").arg(l.remainingTime()))
|
||||
s.nospace() << " preferred:" << printable(e.preferredLifetime())
|
||||
<< " valid:" << printable(e.validityLifetime());
|
||||
#undef printable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::consistencyCheck()
|
||||
{
|
||||
QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
|
||||
QSet<QString> interfaceNames;
|
||||
QList<int> interfaceIndexes;
|
||||
|
||||
foreach (const QNetworkInterface &iface, ifaces) {
|
||||
QVERIFY(iface.isValid());
|
||||
QVERIFY2(!interfaceNames.contains(iface.name()),
|
||||
"duplicate name = " + iface.name().toLocal8Bit());
|
||||
interfaceNames << iface.name();
|
||||
|
||||
QVERIFY2(!interfaceIndexes.contains(iface.index()),
|
||||
"duplicate index = " + QByteArray::number(iface.index()));
|
||||
if (iface.index())
|
||||
interfaceIndexes << iface.index();
|
||||
|
||||
QVERIFY(iface.maximumTransmissionUnit() >= 0);
|
||||
|
||||
const QList<QNetworkAddressEntry> addresses = iface.addressEntries();
|
||||
for (auto entry : addresses) {
|
||||
QVERIFY(entry.ip().protocol() != QAbstractSocket::UnknownNetworkLayerProtocol);
|
||||
if (!entry.preferredLifetime().isForever() || !entry.validityLifetime().isForever())
|
||||
QVERIFY(entry.isLifetimeKnown());
|
||||
if (!entry.validityLifetime().isForever())
|
||||
QVERIFY(entry.isTemporary());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::loopbackIPv4()
|
||||
{
|
||||
QList<QHostAddress> all = QNetworkInterface::allAddresses();
|
||||
QVERIFY(all.contains(QHostAddress(QHostAddress::LocalHost)));
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::loopbackIPv6()
|
||||
{
|
||||
if (!isIPv6Working())
|
||||
QSKIP("IPv6 not active on this machine");
|
||||
QList<QHostAddress> all = QNetworkInterface::allAddresses();
|
||||
QVERIFY(all.contains(QHostAddress(QHostAddress::LocalHostIPv6)));
|
||||
}
|
||||
void tst_QNetworkInterface::localAddress_data()
|
||||
{
|
||||
bool ipv6 = isIPv6Working();
|
||||
QTest::addColumn<QHostAddress>("target");
|
||||
|
||||
QTest::newRow("localhost-ipv4") << QHostAddress(QHostAddress::LocalHost);
|
||||
if (ipv6)
|
||||
QTest::newRow("localhost-ipv6") << QHostAddress(QHostAddress::LocalHostIPv6);
|
||||
|
||||
if (hasNetworkServer)
|
||||
QTest::newRow("test-server") << QtNetworkSettings::httpServerIp();
|
||||
|
||||
QSet<QHostAddress> added;
|
||||
const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
|
||||
for (const QNetworkInterface &iface : ifaces) {
|
||||
if ((iface.flags() & QNetworkInterface::IsUp) == 0)
|
||||
continue;
|
||||
const QList<QNetworkAddressEntry> addrs = iface.addressEntries();
|
||||
for (const QNetworkAddressEntry &entry : addrs) {
|
||||
QHostAddress addr = entry.ip();
|
||||
if (addr.isLoopback())
|
||||
continue; // added above
|
||||
|
||||
if (addr.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
// add an IPv4 address with bits in the host portion of the address flipped
|
||||
quint32 ip4 = entry.ip().toIPv4Address();
|
||||
addr.setAddress(ip4 ^ ~entry.netmask().toIPv4Address());
|
||||
} else if (!ipv6 || entry.prefixLength() != 64) {
|
||||
continue;
|
||||
} else {
|
||||
// add a random node in this IPv6 network
|
||||
quint64 randomid = qFromBigEndian(Q_UINT64_C(0x8f41f072e5733caa));
|
||||
QIPv6Address ip6 = addr.toIPv6Address();
|
||||
memcpy(&ip6[8], &randomid, sizeof(randomid));
|
||||
addr.setAddress(ip6);
|
||||
}
|
||||
|
||||
if (added.contains(addr))
|
||||
continue;
|
||||
added.insert(addr);
|
||||
|
||||
QTest::addRow("%s-%s", qPrintable(iface.name()), qPrintable(addr.toString())) << addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::localAddress()
|
||||
{
|
||||
QFETCH(QHostAddress, target);
|
||||
QUdpSocket socket;
|
||||
socket.connectToHost(target, 80);
|
||||
QVERIFY(socket.waitForConnected(5000));
|
||||
|
||||
QHostAddress local = socket.localAddress();
|
||||
|
||||
// find the interface that contains the address QUdpSocket reported
|
||||
QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
|
||||
const QNetworkInterface *outgoingIface = nullptr;
|
||||
for (const QNetworkInterface &iface : ifaces) {
|
||||
QList<QNetworkAddressEntry> addrs = iface.addressEntries();
|
||||
for (const QNetworkAddressEntry &entry : addrs) {
|
||||
if (entry.ip() == local) {
|
||||
outgoingIface = &iface;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outgoingIface)
|
||||
break;
|
||||
}
|
||||
QVERIFY(outgoingIface);
|
||||
|
||||
// we get QVariant() if the QNativeSocketEngine doesn't know how to get the PMTU
|
||||
int pmtu = socket.socketOption(QAbstractSocket::PathMtuSocketOption).toInt();
|
||||
qDebug() << "Connected to" << target.toString() << "via interface" << outgoingIface->name()
|
||||
<< "pmtu" << pmtu;
|
||||
|
||||
// check that the Path MTU is less than or equal the interface's MTU
|
||||
QVERIFY(pmtu <= outgoingIface->maximumTransmissionUnit());
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::interfaceFromXXX_data()
|
||||
{
|
||||
QTest::addColumn<QNetworkInterface>("iface");
|
||||
|
||||
QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces();
|
||||
if (allInterfaces.size() == 0)
|
||||
QSKIP("No interfaces to test!");
|
||||
foreach (QNetworkInterface iface, allInterfaces)
|
||||
QTest::newRow(iface.name().toLocal8Bit()) << iface;
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::interfaceFromXXX()
|
||||
{
|
||||
QFETCH(QNetworkInterface, iface);
|
||||
|
||||
QVERIFY(QNetworkInterface::interfaceFromName(iface.name()).isValid());
|
||||
if (int idx = iface.index()) {
|
||||
QVERIFY(QNetworkInterface::interfaceFromIndex(idx).isValid());
|
||||
QCOMPARE(QNetworkInterface::interfaceNameFromIndex(idx), iface.name());
|
||||
QCOMPARE(QNetworkInterface::interfaceIndexFromName(iface.name()), idx);
|
||||
}
|
||||
foreach (QNetworkAddressEntry entry, iface.addressEntries()) {
|
||||
QVERIFY(!entry.ip().isNull());
|
||||
|
||||
if (!entry.netmask().isNull()) {
|
||||
QCOMPARE(entry.netmask().protocol(), entry.ip().protocol());
|
||||
|
||||
// if the netmask is known, the broadcast is known
|
||||
// but only for IPv4 (there is no such thing as broadcast in IPv6)
|
||||
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
QVERIFY(!entry.broadcast().isNull());
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry.broadcast().isNull())
|
||||
QCOMPARE(entry.broadcast().protocol(), entry.ip().protocol());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::copyInvalidInterface()
|
||||
{
|
||||
// Force a copy of an interfaces that isn't likely to exist
|
||||
QNetworkInterface i = QNetworkInterface::interfaceFromName("plopp");
|
||||
QVERIFY(!i.isValid());
|
||||
|
||||
QCOMPARE(i.index(), 0);
|
||||
QVERIFY(i.name().isEmpty());
|
||||
QVERIFY(i.humanReadableName().isEmpty());
|
||||
QVERIFY(i.hardwareAddress().isEmpty());
|
||||
QCOMPARE(int(i.flags()), 0);
|
||||
QVERIFY(i.addressEntries().isEmpty());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNetworkInterface)
|
||||
#include "tst_qnetworkinterface.moc"
|
13
tests/auto/network/kernel/qnetworkproxy/CMakeLists.txt
Normal file
13
tests/auto/network/kernel/qnetworkproxy/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qnetworkproxy Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qnetworkproxy
|
||||
SOURCES
|
||||
tst_qnetworkproxy.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
#include <qdebug.h>
|
||||
#include <qnetworkproxy.h>
|
||||
|
||||
class tst_QNetworkProxy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QNetworkProxy();
|
||||
virtual ~tst_QNetworkProxy();
|
||||
|
||||
private slots:
|
||||
void getSetCheck();
|
||||
void capabilitiesPerType();
|
||||
};
|
||||
|
||||
tst_QNetworkProxy::tst_QNetworkProxy()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QNetworkProxy::~tst_QNetworkProxy()
|
||||
{
|
||||
}
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QNetworkProxy::getSetCheck()
|
||||
{
|
||||
QNetworkProxy obj1;
|
||||
// quint16 QNetworkProxy::port()
|
||||
// void QNetworkProxy::setPort(quint16)
|
||||
obj1.setPort(quint16(0));
|
||||
QCOMPARE(quint16(0), obj1.port());
|
||||
obj1.setPort(quint16(0xffff));
|
||||
QCOMPARE(quint16(0xffff), obj1.port());
|
||||
|
||||
obj1.setType(QNetworkProxy::DefaultProxy);
|
||||
QCOMPARE(obj1.type(), QNetworkProxy::DefaultProxy);
|
||||
obj1.setType(QNetworkProxy::HttpProxy);
|
||||
QCOMPARE(obj1.type(), QNetworkProxy::HttpProxy);
|
||||
obj1.setType(QNetworkProxy::Socks5Proxy);
|
||||
QCOMPARE(obj1.type(), QNetworkProxy::Socks5Proxy);
|
||||
}
|
||||
|
||||
void tst_QNetworkProxy::capabilitiesPerType()
|
||||
{
|
||||
QNetworkProxy proxy(QNetworkProxy::Socks5Proxy);
|
||||
QVERIFY(proxy.capabilities() & QNetworkProxy::TunnelingCapability);
|
||||
QVERIFY(proxy.capabilities() & QNetworkProxy::HostNameLookupCapability);
|
||||
QVERIFY(proxy.capabilities() & QNetworkProxy::UdpTunnelingCapability);
|
||||
|
||||
proxy.setType(QNetworkProxy::NoProxy);
|
||||
// verify that the capabilities changed
|
||||
QVERIFY(!(proxy.capabilities() & QNetworkProxy::HostNameLookupCapability));
|
||||
QVERIFY(proxy.capabilities() & QNetworkProxy::UdpTunnelingCapability);
|
||||
|
||||
proxy.setType(QNetworkProxy::HttpProxy);
|
||||
QVERIFY(proxy.capabilities() & QNetworkProxy::HostNameLookupCapability);
|
||||
QVERIFY(!(proxy.capabilities() & QNetworkProxy::UdpTunnelingCapability));
|
||||
|
||||
// now set the capabilities on stone:
|
||||
proxy.setCapabilities(QNetworkProxy::TunnelingCapability | QNetworkProxy::UdpTunnelingCapability);
|
||||
QCOMPARE(proxy.capabilities(), QNetworkProxy::TunnelingCapability | QNetworkProxy::UdpTunnelingCapability);
|
||||
|
||||
// changing the type shouldn't change the capabilities any more
|
||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||
QCOMPARE(proxy.capabilities(), QNetworkProxy::TunnelingCapability | QNetworkProxy::UdpTunnelingCapability);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNetworkProxy)
|
||||
#include "tst_qnetworkproxy.moc"
|
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qnetworkproxyfactory Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qnetworkproxyfactory
|
||||
SOURCES
|
||||
tst_qnetworkproxyfactory.cpp
|
||||
LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
@ -0,0 +1,294 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QtTest/QTest>
|
||||
#include <QtTest/QTestEventLoop>
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
#include <qdebug.h>
|
||||
#include <qnetworkproxy.h>
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkInterface>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QList>
|
||||
#include <QSysInfo>
|
||||
#include <QThread>
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
class tst_QNetworkProxyFactory : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QNetworkProxyFactory();
|
||||
|
||||
class QDebugProxyFactory : public QNetworkProxyFactory
|
||||
{
|
||||
public:
|
||||
QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()) override
|
||||
{
|
||||
returnedList = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||
requestCounter++;
|
||||
return returnedList;
|
||||
}
|
||||
QList<QNetworkProxy> returnedList;
|
||||
|
||||
static int requestCounter;
|
||||
};
|
||||
|
||||
private slots:
|
||||
void systemProxyForQueryCalledFromThread();
|
||||
void systemProxyForQuery_data();
|
||||
void systemProxyForQuery() const;
|
||||
void systemProxyForQuery_local();
|
||||
void genericSystemProxy();
|
||||
void genericSystemProxy_data();
|
||||
|
||||
private:
|
||||
QString formatProxyName(const QNetworkProxy & proxy) const;
|
||||
QDebugProxyFactory *factory;
|
||||
};
|
||||
|
||||
int tst_QNetworkProxyFactory::QDebugProxyFactory::requestCounter = 0;
|
||||
|
||||
tst_QNetworkProxyFactory::tst_QNetworkProxyFactory()
|
||||
{
|
||||
factory = new QDebugProxyFactory;
|
||||
QNetworkProxyFactory::setApplicationProxyFactory(factory);
|
||||
}
|
||||
|
||||
QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) const
|
||||
{
|
||||
QString proxyName;
|
||||
if (!proxy.user().isNull())
|
||||
proxyName.append(QString("%1:%2@").arg(proxy.user(), proxy.password()));
|
||||
proxyName.append(QString("%1:%2").arg(proxy.hostName()).arg(proxy.port()));
|
||||
proxyName.append(QString(" (type=%1, capabilities=%2)").arg(proxy.type()).arg(proxy.capabilities()));
|
||||
|
||||
return proxyName;
|
||||
}
|
||||
|
||||
void tst_QNetworkProxyFactory::systemProxyForQuery_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
QTest::addColumn<QUrl>("url");
|
||||
QTest::addColumn<QString>("tag");
|
||||
QTest::addColumn<QString>("hostName");
|
||||
QTest::addColumn<int>("port");
|
||||
QTest::addColumn<int>("requiredCapabilities");
|
||||
|
||||
//URLs
|
||||
QTest::newRow("http") << (int)QNetworkProxyQuery::UrlRequest << QUrl("http://qt-project.org") << QString() << QString() << 0 << 0;
|
||||
//windows: "intranet" should be bypassed if "bypass proxy server for local addresses" is ticked
|
||||
QTest::newRow("intranet") << (int)QNetworkProxyQuery::UrlRequest << QUrl("http://qt-test-server") << QString() << QString() << 0 << 0;
|
||||
//windows: "intranet2" should be bypassed if "*.local" is in the exceptions list (advanced settings)
|
||||
QTest::newRow("intranet2") << (int)QNetworkProxyQuery::UrlRequest << QUrl("http://qt-test-server.local") << QString() << QString() << 0 << 0;
|
||||
QTest::newRow("https") << (int)QNetworkProxyQuery::UrlRequest << QUrl("https://qt-project.org") << QString() << QString() << 0 << (int)QNetworkProxy::TunnelingCapability;
|
||||
QTest::newRow("ftp") << (int)QNetworkProxyQuery::UrlRequest << QUrl("ftp://qt-project.org") << QString() << QString() << 0 << 0;
|
||||
|
||||
//TCP
|
||||
QTest::newRow("imap") << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString() << QString("qt-project.org") << 0 << (int)QNetworkProxy::TunnelingCapability;
|
||||
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()) {
|
||||
QTest::newRow(qPrintable(address.toString())) << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString() << address.toString() << 0 << 0;
|
||||
}
|
||||
|
||||
//UDP
|
||||
QTest::newRow("udp") << (int)QNetworkProxyQuery::UdpSocket << QUrl() << QString() << QString() << 0 << (int)QNetworkProxy::UdpTunnelingCapability;
|
||||
|
||||
//Protocol tags
|
||||
QTest::newRow("http-tag") << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString("http") << QString("qt-project.org") << 80 << (int)QNetworkProxy::TunnelingCapability;
|
||||
QTest::newRow("ftp-tag") << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString("ftp") << QString("qt-project.org") << 21 << (int)QNetworkProxy::TunnelingCapability;
|
||||
QTest::newRow("https-tag") << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString("https") << QString("qt-project.org") << 443 << (int)QNetworkProxy::TunnelingCapability;
|
||||
#ifdef Q_OS_WIN
|
||||
//in Qt 4.8, "socks" would get the socks proxy, but we don't want to enforce that for all platforms
|
||||
QTest::newRow("socks-tag") << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString("socks") << QString("qt-project.org") << 21 << (int)(QNetworkProxy::TunnelingCapability | QNetworkProxy::ListeningCapability);
|
||||
#endif
|
||||
//windows: ssh is not a tag provided by the os, but any tunneling proxy is acceptable
|
||||
QTest::newRow("ssh-tag") << (int)QNetworkProxyQuery::TcpSocket << QUrl() << QString("ssh") << QString("qt-project.org") << 22 << (int)QNetworkProxy::TunnelingCapability;
|
||||
|
||||
//Server protocol tags (ftp/http proxies are no good, we need socks or nothing)
|
||||
QTest::newRow("http-server-tag") << (int)QNetworkProxyQuery::TcpServer << QUrl() << QString("http") << QString() << 80 << (int)QNetworkProxy::ListeningCapability;
|
||||
QTest::newRow("ftp-server-tag") << (int)QNetworkProxyQuery::TcpServer << QUrl() << QString("ftp") << QString() << 21 << (int)QNetworkProxy::ListeningCapability;
|
||||
QTest::newRow("imap-server-tag") << (int)QNetworkProxyQuery::TcpServer << QUrl() << QString("imap") << QString() << 143 << (int)QNetworkProxy::ListeningCapability;
|
||||
|
||||
//UDP protocol tag
|
||||
QTest::newRow("sip-udp-tag") << (int)QNetworkProxyQuery::UdpSocket << QUrl() << QString("sip") << QString("qt-project.org") << 5061 << (int)QNetworkProxy::UdpTunnelingCapability;
|
||||
}
|
||||
|
||||
void tst_QNetworkProxyFactory::systemProxyForQuery() const
|
||||
{
|
||||
QFETCH(int, type);
|
||||
QFETCH(QUrl, url);
|
||||
QFETCH(QString, tag);
|
||||
QFETCH(QString, hostName);
|
||||
QFETCH(int, port);
|
||||
QFETCH(int, requiredCapabilities);
|
||||
|
||||
QNetworkProxyQuery query;
|
||||
|
||||
switch (type) {
|
||||
case QNetworkProxyQuery::UrlRequest:
|
||||
query = QNetworkProxyQuery(url);
|
||||
break;
|
||||
case QNetworkProxyQuery::TcpSocket:
|
||||
case QNetworkProxyQuery::UdpSocket:
|
||||
query = QNetworkProxyQuery(hostName, port, tag, QNetworkProxyQuery::QueryType(type));
|
||||
break;
|
||||
case QNetworkProxyQuery::TcpServer:
|
||||
query = QNetworkProxyQuery(quint16(port), tag);
|
||||
break;
|
||||
}
|
||||
|
||||
QElapsedTimer sw;
|
||||
sw.start();
|
||||
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) {
|
||||
QVERIFY((requiredCapabilities == 0) || (proxy.capabilities() & requiredCapabilities));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkProxyFactory::systemProxyForQuery_local()
|
||||
{
|
||||
QList<QNetworkProxy> list;
|
||||
const QString proxyHost("myproxy.test.com");
|
||||
|
||||
// set an arbitrary proxy
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, proxyHost, 80));
|
||||
factory = 0;
|
||||
|
||||
// localhost
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://localhost/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("localhost"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
|
||||
// 127.0.0.1
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://127.0.0.1/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("127.0.0.1"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
|
||||
// [::1]
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://[::1]/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("[::1]"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
|
||||
// an arbitrary host
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://another.host.com/")));
|
||||
QVERIFY((!list.isEmpty()) && (list[0].hostName() == proxyHost));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("another.host.com"), 80));
|
||||
QVERIFY((!list.isEmpty()) && (list[0].hostName() == proxyHost));
|
||||
|
||||
// disable proxy
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
|
||||
factory = 0;
|
||||
|
||||
// localhost
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://localhost/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("localhost"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
|
||||
// 127.0.0.1
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://127.0.0.1/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("127.0.0.1"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
|
||||
// [::1]
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://[::1]/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("[::1]"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
|
||||
// an arbitrary host
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://another.host.com/")));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("another.host.com"), 80));
|
||||
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QNetworkProxy::ProxyType)
|
||||
|
||||
void tst_QNetworkProxyFactory::genericSystemProxy()
|
||||
{
|
||||
QFETCH(QByteArray, envVar);
|
||||
QFETCH(QByteArray, url);
|
||||
QFETCH(QNetworkProxy::ProxyType, proxyType);
|
||||
QFETCH(QString, hostName);
|
||||
QFETCH(int, port);
|
||||
|
||||
qputenv(envVar, url);
|
||||
const QList<QNetworkProxy> systemProxy = QNetworkProxyFactory::systemProxyForQuery();
|
||||
QCOMPARE(systemProxy.size(), 1);
|
||||
QCOMPARE(systemProxy.first().type(), proxyType);
|
||||
QCOMPARE(systemProxy.first().hostName(), hostName);
|
||||
QCOMPARE(systemProxy.first().port(), static_cast<quint16>(port));
|
||||
qunsetenv(envVar);
|
||||
}
|
||||
|
||||
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");
|
||||
QTest::addColumn<QString>("hostName");
|
||||
QTest::addColumn<int>("port");
|
||||
|
||||
QTest::newRow("no proxy") << QByteArray("http_proxy") << QByteArray() << QNetworkProxy::NoProxy
|
||||
<< QString() << 0;
|
||||
QTest::newRow("socks5") << QByteArray("http_proxy") << QByteArray("socks5://127.0.0.1:4242")
|
||||
<< 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
|
||||
{
|
||||
protected:
|
||||
void run() override
|
||||
{
|
||||
proxies = QNetworkProxyFactory::systemProxyForQuery(query);
|
||||
}
|
||||
public:
|
||||
QNetworkProxyQuery query;
|
||||
QList<QNetworkProxy> proxies;
|
||||
};
|
||||
|
||||
//regression test for QTBUG-18799
|
||||
void tst_QNetworkProxyFactory::systemProxyForQueryCalledFromThread()
|
||||
{
|
||||
if (QSysInfo::productType() == QLatin1String("windows") && QSysInfo::productVersion() == QLatin1String("7sp1")) {
|
||||
QSKIP("This test fails by the systemProxyForQuery() call hanging - QTQAINFRA-1200");
|
||||
}
|
||||
QUrl url(QLatin1String("http://qt-project.org"));
|
||||
QNetworkProxyQuery query(url);
|
||||
QSPFQThread thread;
|
||||
thread.query = query;
|
||||
connect(&thread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||
thread.start();
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
QVERIFY(thread.isFinished());
|
||||
QCOMPARE(thread.proxies, QNetworkProxyFactory::systemProxyForQuery(query));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNetworkProxyFactory)
|
||||
#include "tst_qnetworkproxyfactory.moc"
|
Reference in New Issue
Block a user