/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** 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 either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** 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.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ // Just to get Q_OS_SYMBIAN #include #if defined(_WIN32) && !defined(Q_OS_SYMBIAN) #include #else #include #include #define SOCKET int #define INVALID_SOCKET -1 #endif #include #ifndef Q_OS_WIN #include #include #endif #include #include #include #include #include #include #include #include #ifdef TEST_QNETWORK_PROXY # include Q_DECLARE_METATYPE(QNetworkProxy) Q_DECLARE_METATYPE(QList) #endif #include "../network-settings.h" //TESTED_CLASS= //TESTED_FILES= class tst_QTcpServer : public QObject { Q_OBJECT public: tst_QTcpServer(); virtual ~tst_QTcpServer(); public slots: void initTestCase_data(); void init(); void cleanup(); private slots: void getSetCheck(); void constructing(); void clientServerLoop(); void ipv6Server(); void ipv4LoopbackPerformanceTest(); void ipv6LoopbackPerformanceTest(); void ipv4PerformanceTest(); void crashTests(); void maxPendingConnections(); void listenError(); void waitForConnectionTest(); void setSocketDescriptor(); void listenWhileListening(); void addressReusable(); void setNewSocketDescriptorBlocking(); #ifdef TEST_QNETWORK_PROXY void invalidProxy_data(); void invalidProxy(); void proxyFactory_data(); void proxyFactory(); #endif }; // Testing get/set functions void tst_QTcpServer::getSetCheck() { QTcpServer obj1; // int QTcpServer::maxPendingConnections() // void QTcpServer::setMaxPendingConnections(int) obj1.setMaxPendingConnections(0); QCOMPARE(0, obj1.maxPendingConnections()); obj1.setMaxPendingConnections(INT_MIN); QCOMPARE(INT_MIN, obj1.maxPendingConnections()); obj1.setMaxPendingConnections(INT_MAX); QCOMPARE(INT_MAX, obj1.maxPendingConnections()); } tst_QTcpServer::tst_QTcpServer() { Q_SET_DEFAULT_IAP } tst_QTcpServer::~tst_QTcpServer() { } void tst_QTcpServer::initTestCase_data() { QTest::addColumn("setProxy"); QTest::addColumn("proxyType"); QTest::newRow("WithoutProxy") << false << 0; #ifdef TEST_QNETWORK_PROXY QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); #endif } void tst_QTcpServer::init() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { #ifdef TEST_QNETWORK_PROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); } #endif } } void tst_QTcpServer::cleanup() { #ifdef TEST_QNETWORK_PROXY QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); #endif } //---------------------------------------------------------------------------------- void tst_QTcpServer::constructing() { QTcpServer socket; // Check the initial state of the QTcpSocket. QCOMPARE(socket.isListening(), false); QCOMPARE((int)socket.serverPort(), 0); QCOMPARE(socket.serverAddress(), QHostAddress()); QCOMPARE(socket.maxPendingConnections(), 30); QCOMPARE(socket.hasPendingConnections(), false); QCOMPARE(socket.socketDescriptor(), -1); QCOMPARE(socket.serverError(), QAbstractSocket::UnknownSocketError); // Check the state of the socket layer? } //---------------------------------------------------------------------------------- void tst_QTcpServer::clientServerLoop() { QTcpServer server; QSignalSpy spy(&server, SIGNAL(newConnection())); QVERIFY(!server.isListening()); QVERIFY(!server.hasPendingConnections()); QVERIFY(server.listen(QHostAddress::Any, 11423)); QVERIFY(server.isListening()); QTcpSocket client; QHostAddress serverAddress = QHostAddress::LocalHost; if (!(server.serverAddress() == QHostAddress::Any)) serverAddress = server.serverAddress(); client.connectToHost(serverAddress, server.serverPort()); QVERIFY(client.waitForConnected(5000)); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.hasPendingConnections()); QCOMPARE(spy.count(), 1); QTcpSocket *serverSocket = server.nextPendingConnection(); QVERIFY(serverSocket != 0); QVERIFY(serverSocket->write("Greetings, client!\n", 19) == 19); serverSocket->flush(); QVERIFY(client.waitForReadyRead(5000)); QByteArray arr = client.readAll(); QCOMPARE(arr.constData(), "Greetings, client!\n"); QVERIFY(client.write("Well, hello to you!\n", 20) == 20); client.flush(); QVERIFY(serverSocket->waitForReadyRead(5000)); arr = serverSocket->readAll(); QCOMPARE(arr.constData(), "Well, hello to you!\n"); } //---------------------------------------------------------------------------------- void tst_QTcpServer::ipv6Server() { #if defined(Q_OS_SYMBIAN) QSKIP("Symbian: IPv6 is not yet supported", SkipAll); #endif //### need to enter the event loop for the server to get the connection ?? ( windows) QTcpServer server; if (!server.listen(QHostAddress::LocalHostIPv6, 8944)) { QVERIFY(server.serverError() == QAbstractSocket::UnsupportedSocketOperationError); return; } QVERIFY(server.serverPort() == 8944); QVERIFY(server.serverAddress() == QHostAddress::LocalHostIPv6); QTcpSocket client; client.connectToHost("::1", 8944); QVERIFY(client.waitForConnected(5000)); QVERIFY(server.waitForNewConnection()); QVERIFY(server.hasPendingConnections()); QTcpSocket *serverSocket = 0; QVERIFY((serverSocket = server.nextPendingConnection())); } //---------------------------------------------------------------------------------- void tst_QTcpServer::ipv4LoopbackPerformanceTest() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); QVERIFY(server.isListening()); QTcpSocket clientA; clientA.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(clientA.waitForConnected(5000)); QVERIFY(clientA.state() == QAbstractSocket::ConnectedState); QVERIFY(server.waitForNewConnection()); QTcpSocket *clientB = server.nextPendingConnection(); QVERIFY(clientB); #if defined(Q_WS_WIN) if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { QSKIP("Dont run performance tests on QSysInfo::WV_DOS_based systems, overloads the system", SkipAll); } else #endif { QByteArray buffer(16384, '@'); QTime stopWatch; stopWatch.start(); qlonglong totalWritten = 0; while (stopWatch.elapsed() < 5000) { QVERIFY(clientA.write(buffer.data(), buffer.size()) > 0); clientA.flush(); totalWritten += buffer.size(); while (clientB->waitForReadyRead(100)) { if (clientB->bytesAvailable() == 16384) break; } clientB->read(buffer.data(), buffer.size()); clientB->write(buffer.data(), buffer.size()); clientB->flush(); totalWritten += buffer.size(); while (clientA.waitForReadyRead(100)) { if (clientA.bytesAvailable() == 16384) break; } clientA.read(buffer.data(), buffer.size()); } qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s", server.serverAddress().toString().toLatin1().constData(), totalWritten / (1024.0 * 1024.0), stopWatch.elapsed() / 1000.0, (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024)); } delete clientB; } //---------------------------------------------------------------------------------- void tst_QTcpServer::ipv6LoopbackPerformanceTest() { #if defined(Q_OS_SYMBIAN) QSKIP("Symbian: IPv6 is not yet supported", SkipAll); #endif QTcpServer server; if (!server.listen(QHostAddress::LocalHostIPv6, 0)) { QVERIFY(server.serverError() == QAbstractSocket::UnsupportedSocketOperationError); } else { QTcpSocket clientA; clientA.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(clientA.waitForConnected(5000)); QVERIFY(server.waitForNewConnection(5000)); QTcpSocket *clientB = server.nextPendingConnection(); QVERIFY(clientB); QByteArray buffer(16384, '@'); QTime stopWatch; stopWatch.start(); qlonglong totalWritten = 0; while (stopWatch.elapsed() < 5000) { clientA.write(buffer.data(), buffer.size()); clientA.flush(); totalWritten += buffer.size(); while (clientB->waitForReadyRead(100)) { if (clientB->bytesAvailable() == 16384) break; } clientB->read(buffer.data(), buffer.size()); clientB->write(buffer.data(), buffer.size()); clientB->flush(); totalWritten += buffer.size(); while (clientA.waitForReadyRead(100)) { if (clientA.bytesAvailable() == 16384) break; } clientA.read(buffer.data(), buffer.size()); } qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s", server.serverAddress().toString().toLatin1().constData(), totalWritten / (1024.0 * 1024.0), stopWatch.elapsed() / 1000.0, (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024)); delete clientB; } } //---------------------------------------------------------------------------------- void tst_QTcpServer::ipv4PerformanceTest() { QTcpSocket probeSocket; probeSocket.connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(probeSocket.waitForConnected(5000)); QTcpServer server; QVERIFY(server.listen(probeSocket.localAddress(), 0)); QTcpSocket clientA; clientA.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(clientA.waitForConnected(5000)); QVERIFY(server.waitForNewConnection(5000)); QTcpSocket *clientB = server.nextPendingConnection(); QVERIFY(clientB); #if defined(Q_WS_WIN) if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { QSKIP("Dont run performance tests on QSysInfo::WV_DOS_based systems, overloads the system", SkipAll); } else #endif { QByteArray buffer(16384, '@'); QTime stopWatch; stopWatch.start(); qlonglong totalWritten = 0; while (stopWatch.elapsed() < 5000) { qlonglong writtenA = clientA.write(buffer.data(), buffer.size()); clientA.flush(); totalWritten += buffer.size(); while (clientB->waitForReadyRead(100)) { if (clientB->bytesAvailable() == writtenA) break; } clientB->read(buffer.data(), buffer.size()); qlonglong writtenB = clientB->write(buffer.data(), buffer.size()); clientB->flush(); totalWritten += buffer.size(); while (clientA.waitForReadyRead(100)) { if (clientA.bytesAvailable() == writtenB) break; } clientA.read(buffer.data(), buffer.size()); } qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s", probeSocket.localAddress().toString().toLatin1().constData(), totalWritten / (1024.0 * 1024.0), stopWatch.elapsed() / 1000.0, (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024)); } delete clientB; } //---------------------------------------------------------------------------------- void tst_QTcpServer::crashTests() { QTcpServer server; server.close(); QVERIFY(server.listen()); } //---------------------------------------------------------------------------------- void tst_QTcpServer::maxPendingConnections() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { #ifdef TEST_QNETWORK_PROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("With socks5 only 1 connection is allowed ever", SkipAll); } #endif } //### sees to fail sometimes ... a timing issue with the test on windows QTcpServer server; server.setMaxPendingConnections(2); QTcpSocket socket1; QTcpSocket socket2; QTcpSocket socket3; QVERIFY(server.listen()); socket1.connectToHost(QHostAddress::LocalHost, server.serverPort()); socket2.connectToHost(QHostAddress::LocalHost, server.serverPort()); socket3.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.hasPendingConnections()); QVERIFY(server.nextPendingConnection()); QVERIFY(server.hasPendingConnections()); QVERIFY(server.nextPendingConnection()); QVERIFY(!server.hasPendingConnections()); QCOMPARE(server.nextPendingConnection(), (QTcpSocket*)0); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.hasPendingConnections()); QVERIFY(server.nextPendingConnection()); } //---------------------------------------------------------------------------------- void tst_QTcpServer::listenError() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { #ifdef TEST_QNETWORK_PROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("With socks5 we can not make hard requirements on the address or port", SkipAll); } #endif } QTcpServer server; QVERIFY(!server.listen(QHostAddress("1.2.3.4"), 0)); QCOMPARE(server.serverError(), QAbstractSocket::SocketAddressNotAvailableError); QCOMPARE(server.errorString().toLatin1().constData(), "The address is not available"); } class ThreadConnector : public QThread { public: ThreadConnector(const QHostAddress &host, quint16 port) : host(host), port(port) { } ~ThreadConnector() { wait(); } protected: void run() { sleep(2); QTcpSocket socket; socket.connectToHost(host, port); QEventLoop loop; QTimer::singleShot(5000, &loop, SLOT(quit())); loop.exec(); } private: QHostAddress host; quint16 port; }; //---------------------------------------------------------------------------------- void tst_QTcpServer::waitForConnectionTest() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { #ifdef TEST_QNETWORK_PROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("Localhost servers don't work well with SOCKS5", SkipAll); } #endif } QTcpSocket findLocalIpSocket; findLocalIpSocket.connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(findLocalIpSocket.waitForConnected(2000)); QTcpServer server; bool timeout = false; QVERIFY(server.listen(findLocalIpSocket.localAddress())); QVERIFY(!server.waitForNewConnection(1000, &timeout)); QCOMPARE(server.serverError(), QAbstractSocket::SocketTimeoutError); QVERIFY(timeout); ThreadConnector connector(findLocalIpSocket.localAddress(), server.serverPort()); connector.start(); #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QVERIFY(server.waitForNewConnection(9000, &timeout)); #else QVERIFY(server.waitForNewConnection(3000, &timeout)); #endif QVERIFY(!timeout); } //---------------------------------------------------------------------------------- void tst_QTcpServer::setSocketDescriptor() { QTcpServer server; QVERIFY(!server.setSocketDescriptor(42)); QCOMPARE(server.serverError(), QAbstractSocket::UnsupportedSocketOperationError); #ifdef Q_OS_WIN // ensure winsock is started WSADATA wsaData; QVERIFY(WSAStartup(MAKEWORD(2,0), &wsaData) == NO_ERROR); #endif SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); QVERIFY(sock != INVALID_SOCKET); sockaddr_in sin; memset(&sin, 0, sizeof(sockaddr_in)); sin.sin_family = AF_INET; sin.sin_port = 0; sin.sin_addr.s_addr = 0x00000000; QVERIFY(::bind(sock, (sockaddr*)&sin, sizeof(sockaddr_in)) == 0); QVERIFY(::listen(sock, 10) == 0); QVERIFY(server.setSocketDescriptor(sock)); #ifdef Q_OS_WIN WSACleanup(); #endif } //---------------------------------------------------------------------------------- void tst_QTcpServer::listenWhileListening() { QTcpServer server; QVERIFY(server.listen()); QTest::ignoreMessage(QtWarningMsg, "QTcpServer::listen() called when already listening"); QVERIFY(!server.listen()); } //---------------------------------------------------------------------------------- class SeverWithBlockingSockets : public QTcpServer { public: SeverWithBlockingSockets() : ok(false) { } bool ok; protected: void incomingConnection(int socketDescriptor) { // how a user woulddo it (qabstractsocketengine is not public) unsigned long arg = 0; #if defined(Q_OS_SYMBIAN) arg = fcntl(socketDescriptor, F_GETFL, NULL); arg &= (~O_NONBLOCK); ok = ::fcntl(socketDescriptor, F_SETFL, arg) != -1; #elif defined(Q_OS_WIN) ok = ::ioctlsocket(socketDescriptor, FIONBIO, &arg) == 0; ::closesocket(socketDescriptor); #else ok = ::ioctl(socketDescriptor, FIONBIO, &arg) == 0; ::close(socketDescriptor); #endif } }; void tst_QTcpServer::addressReusable() { #if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86) QSKIP("Symbian: Emulator does not support process launching", SkipAll ); #endif #if defined(QT_NO_PROCESS) QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll); #else QFETCH_GLOBAL(bool, setProxy); if (setProxy) { #ifdef TEST_QNETWORK_PROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("With socks5 this test does not make senans at the momment", SkipAll); } #endif } #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QString signalName = QString::fromLatin1("/test_signal.txt"); QFile::remove(signalName); // The crashingServer process will crash once it gets a connection. QProcess process; process.start("crashingServer/crashingServer"); int waitCount = 5; while (waitCount-- && !QFile::exists(signalName)) QTest::qWait(1000); QVERIFY(QFile::exists(signalName)); QFile::remove(signalName); #else // The crashingServer process will crash once it gets a connection. QProcess process; process.start("crashingServer/crashingServer"); QVERIFY(process.waitForReadyRead(5000)); #endif QTcpSocket socket; socket.connectToHost(QHostAddress::LocalHost, 49199); QVERIFY(socket.waitForConnected(5000)); QVERIFY(process.waitForFinished(5000)); // Give the system some time. QTest::qSleep(10); QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 49199)); #endif } void tst_QTcpServer::setNewSocketDescriptorBlocking() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { #ifdef TEST_QNETWORK_PROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("With socks5 we can not make the socket descripter blocking", SkipAll); } #endif } SeverWithBlockingSockets server; QVERIFY(server.listen()); QTcpSocket socket; socket.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.ok); } #ifdef TEST_QNETWORK_PROXY void tst_QTcpServer::invalidProxy_data() { QTest::addColumn("type"); QTest::addColumn("host"); QTest::addColumn("port"); QTest::addColumn("expectedError"); QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << fluke << 143 << int(QAbstractSocket::UnsupportedSocketOperationError); QTest::newRow("http-proxy") << int(QNetworkProxy::HttpProxy) << fluke << 3128 << int(QAbstractSocket::UnsupportedSocketOperationError); QTest::newRow("no-such-host") << int(QNetworkProxy::Socks5Proxy) << "this-host-will-never-exist.troll.no" << 1080 << int(QAbstractSocket::ProxyNotFoundError); QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << fluke << 3128 << int(QAbstractSocket::SocketTimeoutError); } void tst_QTcpServer::invalidProxy() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QFETCH(int, type); QFETCH(QString, host); QFETCH(int, port); QNetworkProxy::ProxyType proxyType = QNetworkProxy::ProxyType(type); QNetworkProxy proxy(proxyType, host, port); QTcpServer server; server.setProxy(proxy); bool listenResult = server.listen(); QVERIFY(!listenResult); QVERIFY(!server.errorString().isEmpty()); // note: the following test is not a hard failure. // Sometimes, error codes change for the better QTEST(int(server.serverError()), "expectedError"); } // copied from tst_qnetworkreply.cpp class MyProxyFactory: public QNetworkProxyFactory { public: int callCount; QList toReturn; QNetworkProxyQuery lastQuery; inline MyProxyFactory() { clear(); } inline void clear() { callCount = 0; toReturn = QList() << QNetworkProxy::DefaultProxy; lastQuery = QNetworkProxyQuery(); } virtual QList queryProxy(const QNetworkProxyQuery &query) { lastQuery = query; ++callCount; return toReturn; } }; void tst_QTcpServer::proxyFactory_data() { QTest::addColumn >("proxyList"); QTest::addColumn("proxyUsed"); QTest::addColumn("fails"); QTest::addColumn("expectedError"); QList proxyList; // tests that do get to listen proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); QTest::newRow("socks5") << proxyList << proxyList.at(0) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128) << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); QTest::newRow("cachinghttp+socks5") << proxyList << proxyList.at(1) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121) << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128) << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); QTest::newRow("ftp+cachinghttp+socks5") << proxyList << proxyList.at(2) << false << int(QAbstractSocket::UnknownSocketError); // tests that fail to listen proxyList.clear(); proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128); QTest::newRow("http") << proxyList << proxyList.at(0) << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128); QTest::newRow("cachinghttp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121); QTest::newRow("ftp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121) << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128); QTest::newRow("ftp+cachinghttp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); } void tst_QTcpServer::proxyFactory() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QFETCH(QList, proxyList); QFETCH(QNetworkProxy, proxyUsed); QFETCH(bool, fails); MyProxyFactory *factory = new MyProxyFactory; factory->toReturn = proxyList; QNetworkProxyFactory::setApplicationProxyFactory(factory); QTcpServer server; bool listenResult = server.listen(); // Verify that the factory was called properly QCOMPARE(factory->callCount, 1); QCOMPARE(factory->lastQuery, QNetworkProxyQuery(0, QString(), QNetworkProxyQuery::TcpServer)); QCOMPARE(listenResult, !fails); QCOMPARE(server.errorString().isEmpty(), !fails); // note: the following test is not a hard failure. // Sometimes, error codes change for the better QTEST(int(server.serverError()), "expectedError"); } #endif QTEST_MAIN(tst_QTcpServer) #include "tst_qtcpserver.moc"