summaryrefslogtreecommitdiffstats
path: root/tests/auto/qhostinfo
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /tests/auto/qhostinfo
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'tests/auto/qhostinfo')
-rw-r--r--tests/auto/qhostinfo/.gitignore1
-rw-r--r--tests/auto/qhostinfo/qhostinfo.pro16
-rw-r--r--tests/auto/qhostinfo/tst_qhostinfo.cpp665
3 files changed, 682 insertions, 0 deletions
diff --git a/tests/auto/qhostinfo/.gitignore b/tests/auto/qhostinfo/.gitignore
new file mode 100644
index 0000000000..432954e8d8
--- /dev/null
+++ b/tests/auto/qhostinfo/.gitignore
@@ -0,0 +1 @@
+tst_qhostinfo
diff --git a/tests/auto/qhostinfo/qhostinfo.pro b/tests/auto/qhostinfo/qhostinfo.pro
new file mode 100644
index 0000000000..97197a9b95
--- /dev/null
+++ b/tests/auto/qhostinfo/qhostinfo.pro
@@ -0,0 +1,16 @@
+load(qttest_p4)
+
+SOURCES += tst_qhostinfo.cpp
+
+QT = core network
+
+wince*: {
+ LIBS += ws2.lib
+} else {
+ win32:LIBS += -lws2_32
+}
+
+symbian: TARGET.CAPABILITY = NetworkServices
+symbian: {
+ INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE
+}
diff --git a/tests/auto/qhostinfo/tst_qhostinfo.cpp b/tests/auto/qhostinfo/tst_qhostinfo.cpp
new file mode 100644
index 0000000000..af0631e1f5
--- /dev/null
+++ b/tests/auto/qhostinfo/tst_qhostinfo.cpp
@@ -0,0 +1,665 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// 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>
+
+// MinGW doesn't provide getaddrinfo(), so we test for Q_OS_WIN
+// and Q_CC_GNU, which indirectly tells us whether we're using MinGW.
+#if defined(Q_OS_WIN) && defined(Q_CC_GNU)
+# define QT_NO_GETADDRINFO
+#endif
+
+#if defined(Q_OS_WIN) && !defined(QT_NO_GETADDRINFO)
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+#include <QtTest/QtTest>
+#include <qcoreapplication.h>
+#include <QDebug>
+#include <QTcpSocket>
+#include <private/qthread_p.h>
+#include <QTcpServer>
+
+#ifndef QT_NO_BEARERMANAGEMENT
+#include <QtNetwork/qnetworkconfigmanager.h>
+#include <QtNetwork/qnetworkconfiguration.h>
+#include <QtNetwork/qnetworksession.h>
+#endif
+
+#include <time.h>
+#include <qlibrary.h>
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <signal.h>
+#endif
+
+#include <qhostinfo.h>
+#include "private/qhostinfo_p.h"
+
+#if !defined(QT_NO_GETADDRINFO)
+# if !defined(Q_OS_WINCE)
+# include <sys/types.h>
+# else
+# include <types.h>
+# endif
+# if defined(Q_OS_UNIX)
+# include <sys/socket.h>
+# endif
+# if !defined(Q_OS_WIN)
+# include <netdb.h>
+# endif
+#endif
+
+#include "../network-settings.h"
+#include "../../shared/util.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+const char * const lupinellaIp = "10.3.4.6";
+
+
+class tst_QHostInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QHostInfo();
+ virtual ~tst_QHostInfo();
+
+
+public slots:
+ void init();
+ void cleanup();
+ void initTestCase();
+
+private slots:
+ void getSetCheck();
+ void staticInformation();
+ void lookupIPv4_data();
+ void lookupIPv4();
+ void lookupIPv6_data();
+ void lookupIPv6();
+ 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();
+ void abortHostLookupInDifferentThread();
+protected slots:
+ void resultsReady(const QHostInfo &);
+
+private:
+ bool ipv6LookupsAvailable;
+ bool ipv6Available;
+ bool lookupDone;
+ int lookupsDoneCounter;
+ QHostInfo lookupResults;
+#ifndef QT_NO_BEARERMANAGEMENT
+ QNetworkConfigurationManager *netConfMan;
+ QNetworkConfiguration networkConfiguration;
+ QScopedPointer<QNetworkSession> networkSession;
+#endif
+};
+
+// 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();
+}
+
+tst_QHostInfo::tst_QHostInfo()
+{
+ Q_SET_DEFAULT_IAP
+}
+
+tst_QHostInfo::~tst_QHostInfo()
+{
+}
+
+void tst_QHostInfo::initTestCase()
+{
+#ifndef QT_NO_BEARERMANAGEMENT
+ //start the default network
+ netConfMan = new QNetworkConfigurationManager(this);
+ networkConfiguration = netConfMan->defaultConfiguration();
+ networkSession.reset(new QNetworkSession(networkConfiguration));
+ if (!networkSession->isOpen()) {
+ networkSession->open();
+ QVERIFY(networkSession->waitForOpened(30000));
+ }
+#endif
+
+#ifdef Q_OS_SYMBIAN
+ ipv6Available = true;
+ ipv6LookupsAvailable = true;
+#else
+ ipv6Available = false;
+ ipv6LookupsAvailable = false;
+#if !defined(QT_NO_GETADDRINFO)
+ // 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("ipv6-test.dev.troll.no", "80", &hint, &result);
+ if (res == 0 && result != 0 && result->ai_family != AF_INET) {
+ freeaddrinfo(result);
+ ipv6LookupsAvailable = true;
+ }
+ }
+#endif
+#endif
+
+ QTcpServer server;
+ if (server.listen(QHostAddress("::1"))) {
+ // We have IPv6 support
+ ipv6Available = 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 independant from each other
+ qt_qhostinfo_clear_cache();
+
+ QFETCH_GLOBAL(bool, cache);
+ qt_qhostinfo_enable_cache(cache);
+}
+
+void tst_QHostInfo::cleanup()
+{
+}
+
+void tst_QHostInfo::lookupIPv4_data()
+{
+ QTest::addColumn<QString>("hostname");
+ QTest::addColumn<QString>("addresses");
+ QTest::addColumn<int>("err");
+
+ // Test server lookup
+ QTest::newRow("lookup_01") << QtNetworkSettings::serverName() << QtNetworkSettings::serverIP().toString() << int(QHostInfo::NoError);
+ QTest::newRow("empty") << "" << "" << int(QHostInfo::HostNotFound);
+
+ QTest::newRow("single_ip4") << "lupinella.troll.no" << lupinellaIp << int(QHostInfo::NoError);
+ QTest::newRow("multiple_ip4") << "multi.dev.troll.no" << "1.2.3.4 1.2.3.5 10.3.3.31" << int(QHostInfo::NoError);
+ QTest::newRow("literal_ip4") << lupinellaIp << lupinellaIp << int(QHostInfo::NoError);
+
+ QTest::newRow("notfound") << "this-name-does-not-exist-hopefully." << "" << int(QHostInfo::HostNotFound);
+
+ QTest::newRow("idn-ace") << "xn--alqualond-34a.troll.no" << "10.3.3.55" << int(QHostInfo::NoError);
+ QTest::newRow("idn-unicode") << QString::fromLatin1("alqualond\353.troll.no") << "10.3.3.55" << int(QHostInfo::NoError);
+}
+
+void tst_QHostInfo::lookupIPv4()
+{
+ QFETCH(QString, hostname);
+ QFETCH(int, err);
+ QFETCH(QString, addresses);
+
+ lookupDone = false;
+ QHostInfo::lookupHost(hostname, this, SLOT(resultsReady(const 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().count(); ++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("ipv6-net") << "www.ipv6-net.org" << "62.93.217.177 2001:618:1401:0:0:0:0:4" << int(QHostInfo::NoError);
+ QTest::newRow("ipv6-test") << "ipv6-test.dev.troll.no" << "2001:638:a00:2:0:0:0:2" << int(QHostInfo::NoError);
+ QTest::newRow("dns6-test") << "dns6-test-dev.troll.no" << "2001:470:1f01:115:0:0:0:10" << int(QHostInfo::NoError);
+ QTest::newRow("multi-dns6") << "multi-dns6-test-dev.troll.no" << "2001:470:1f01:115:0:0:0:11 2001:470:1f01:115:0:0:0:12" << int(QHostInfo::NoError);
+ QTest::newRow("dns46-test") << "dns46-test-dev.troll.no" << "10.3.4.90 2001:470:1f01:115:0:0:0:13" << 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:0:0:0:0: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", SkipAll);
+
+ lookupDone = false;
+ QHostInfo::lookupHost(hostname, this, SLOT(resultsReady(const QHostInfo&)));
+
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QVERIFY(lookupDone);
+
+ QCOMPARE((int)lookupResults.error(), (int)err);
+
+ QStringList tmp;
+ for (int i = 0; i < lookupResults.addresses().count(); ++i)
+ tmp.append(lookupResults.addresses().at(i).toString());
+ tmp.sort();
+
+ QStringList expected = addresses.split(' ');
+ expected.sort();
+
+ QCOMPARE(tmp.join(" ").toLower(), expected.join(" ").toLower());
+}
+
+void tst_QHostInfo::reverseLookup_data()
+{
+ QTest::addColumn<QString>("address");
+ QTest::addColumn<QStringList>("hostNames");
+ QTest::addColumn<int>("err");
+
+ QTest::newRow("trolltech.com") << QString("62.70.27.69") << QStringList(QString("diverse.troll.no")) << 0;
+
+ // ### Use internal DNS instead. Discussed with Andreas.
+ //QTest::newRow("classical.hexago.com") << QString("2001:5c0:0:2::24") << QStringList(QString("classical.hexago.com")) << 0;
+ QTest::newRow("gitorious.org") << QString("87.238.52.168") << QStringList(QString("gitorious.org")) << 0;
+ QTest::newRow("bogus-name") << QString("1::2::3::4") << QStringList() << 1;
+}
+
+void tst_QHostInfo::reverseLookup()
+{
+ QFETCH(QString, address);
+ QFETCH(QStringList, hostNames);
+ QFETCH(int, err);
+
+ if (!ipv6LookupsAvailable && hostNames.contains("classical.hexago.com")) {
+ QSKIP("IPv6 lookups are not supported on this platform", SkipSingle);
+ }
+#if defined(Q_OS_HPUX) && defined(__ia64)
+ if (hostNames.contains("classical.hexago.com"))
+ QSKIP("HP-UX 11i does not support IPv6 reverse lookups.", SkipSingle);
+#endif
+
+ QHostInfo info = QHostInfo::fromName(address);
+
+ if (err == 0) {
+ 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().count(); ++i)
+ tmp.append(hostInfo.addresses().at(i).toString());
+ tmp.sort();
+
+ if ((int)hostInfo.error() != (int)err) {
+ qWarning() << hostname << "=>" << lookupResults.errorString();
+ }
+ QCOMPARE((int)hostInfo.error(), (int)err);
+
+ QStringList expected = addresses.split(' ');
+ expected.sort();
+
+ QCOMPARE(tmp.join(" ").toUpper(), expected.join(" ").toUpper());
+}
+
+void tst_QHostInfo::raceCondition()
+{
+ for (int i = 0; i < 1000; ++i) {
+ QTcpSocket socket;
+ socket.connectToHost("notavalidname.troll.no", 80);
+ }
+}
+
+class LookupThread : public QThread
+{
+protected:
+ inline void run()
+ {
+ QHostInfo info = QHostInfo::fromName("qt.nokia.com");
+ QCOMPARE(info.error(), QHostInfo::NoError);
+ QVERIFY(info.addresses().count() > 0);
+ QCOMPARE(info.addresses().at(0).toString(), QString("87.238.50.178"));
+ }
+};
+
+void tst_QHostInfo::threadSafety()
+{
+ const int nattempts = 5;
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ const int runs = 10;
+#else
+ const int runs = 100;
+#endif
+ 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("qt.nokia.com"), this, SLOT(resultsReady(const 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.count() - 1; k >= 0; --k)
+ QVERIFY(threads.at(k)->wait(60000));
+ foreach (LookupReceiver* receiver, receivers) {
+ QCOMPARE(receiver->result.error(), QHostInfo::NoError);
+ QCOMPARE(receiver->result.addresses().at(0).toString(), QString("87.238.50.178"));
+ 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(const 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 << "www.ovi.com" << "www.nokia.com" << "qt.nokia.com" << "www.trolltech.com" << "troll.no"
+ << "www.qtcentre.org" << "forum.nokia.com" << "www.nokia.com" << "wiki.forum.nokia.com"
+ << "www.nokia.com" << "nokia.de" << "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(const 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 == false);
+ 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 == true);
+ 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 == false);
+ QVERIFY(result.addresses().isEmpty());
+
+ // the slot should have been called 2 times.
+ QCOMPARE(lookupsDoneCounter, 2);
+}
+
+void tst_QHostInfo::resultsReady(const QHostInfo &hi)
+{
+ lookupDone = true;
+ lookupResults = hi;
+ lookupsDoneCounter++;
+ QMetaObject::invokeMethod(&QTestEventLoop::instance(), "exitLoop", Qt::QueuedConnection);
+}
+
+void tst_QHostInfo::abortHostLookup()
+{
+ //reset counter
+ lookupsDoneCounter = 0;
+ bool valid = false;
+ int id = -1;
+ QHostInfo result = qt_qhostinfo_lookup("qt.nokia.com", 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;
+};
+
+void tst_QHostInfo::abortHostLookupInDifferentThread()
+{
+ //reset counter
+ lookupsDoneCounter = 0;
+ bool valid = false;
+ int id = -1;
+ QHostInfo result = qt_qhostinfo_lookup("qt.nokia.com", this, SLOT(resultsReady(QHostInfo)), &valid, &id);
+ QVERIFY(!valid);
+ QThread thread;
+ LookupAborter aborter;
+ aborter.id = id;
+ aborter.moveToThread(&thread);
+ connect(&thread, SIGNAL(started()), &aborter, SLOT(abort()));
+ //it is assumed that the DNS request/response in the backend is slower than it takes to schedule the thread and call abort
+ thread.start();
+ QVERIFY(thread.wait(5000));
+ QTestEventLoop::instance().enterLoop(5);
+ QCOMPARE(lookupsDoneCounter, 0);
+}
+
+QTEST_MAIN(tst_QHostInfo)
+#include "tst_qhostinfo.moc"