mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-06 17:25:24 +08:00
qt 6.5.1 original
This commit is contained in:
20
tests/auto/network/socket/CMakeLists.txt
Normal file
20
tests/auto/network/socket/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(QT_FEATURE_private_tests)
|
||||
add_subdirectory(qhttpsocketengine)
|
||||
add_subdirectory(qtcpsocket)
|
||||
add_subdirectory(qsocks5socketengine)
|
||||
add_subdirectory(platformsocketengine)
|
||||
endif()
|
||||
add_subdirectory(qudpsocket)
|
||||
add_subdirectory(qabstractsocket)
|
||||
if(NOT ANDROID)
|
||||
# QTBUG-87387
|
||||
add_subdirectory(qlocalsocket)
|
||||
# QTBUG-87388
|
||||
add_subdirectory(qtcpserver)
|
||||
endif()
|
||||
if(QT_FEATURE_sctp)
|
||||
add_subdirectory(qsctpsocket)
|
||||
endif()
|
11
tests/auto/network/socket/platformsocketengine/BLACKLIST
Normal file
11
tests/auto/network/socket/platformsocketengine/BLACKLIST
Normal file
@ -0,0 +1,11 @@
|
||||
[tcpLoopbackPerformance]
|
||||
windows-10 msvc-2015
|
||||
windows-7sp1
|
||||
[receiveUrgentData]
|
||||
windows-10 msvc-2015
|
||||
windows-7sp1
|
||||
[serverTest]
|
||||
windows-10 msvc-2015
|
||||
windows-7sp1
|
||||
[tcpLoopbackPerformance]
|
||||
windows
|
@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
## tst_platformsocketengine Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_platformsocketengine
|
||||
SOURCES
|
||||
tst_platformsocketengine.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::NetworkPrivate
|
||||
QT_TEST_SERVER_LIST "cyrus"
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_platformsocketengine CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
@ -0,0 +1,655 @@
|
||||
// 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 <QtTest/QTest>
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
#include <qdatastream.h>
|
||||
#include <qhostaddress.h>
|
||||
#include <qelapsedtimer.h>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_VXWORKS
|
||||
#include <sockLib.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define PLATFORMSOCKETENGINE QNativeSocketEngine
|
||||
#define PLATFORMSOCKETENGINESTRING "QNativeSocketEngine"
|
||||
#include <private/qnativesocketengine_p_p.h>
|
||||
|
||||
#include <qstringlist.h>
|
||||
|
||||
#include "../../../network-settings.h"
|
||||
|
||||
class tst_PlatformSocketEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void construction();
|
||||
void simpleConnectToIMAP();
|
||||
void udpLoopbackTest();
|
||||
void udpIPv6LoopbackTest();
|
||||
void broadcastTest();
|
||||
void serverTest();
|
||||
void udpLoopbackPerformance();
|
||||
void tcpLoopbackPerformance();
|
||||
#if 0
|
||||
void readWriteBufferSize();
|
||||
#endif
|
||||
void bind();
|
||||
void networkError();
|
||||
void setSocketDescriptor();
|
||||
void invalidSend();
|
||||
void receiveUrgentData();
|
||||
void tooManySockets();
|
||||
};
|
||||
|
||||
void tst_PlatformSocketEngine::initTestCase()
|
||||
{
|
||||
#ifdef QT_TEST_SERVER
|
||||
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143));
|
||||
#else
|
||||
if (!QtNetworkSettings::verifyTestNetworkSettings())
|
||||
QSKIP("No network test server available");
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::construction()
|
||||
{
|
||||
PLATFORMSOCKETENGINE socketDevice;
|
||||
|
||||
QVERIFY(!socketDevice.isValid());
|
||||
|
||||
// Initialize device
|
||||
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QVERIFY(socketDevice.isValid());
|
||||
QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol);
|
||||
QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket);
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
QVERIFY(socketDevice.socketDescriptor() != -1);
|
||||
QCOMPARE(socketDevice.localAddress(), QHostAddress());
|
||||
QCOMPARE(socketDevice.localPort(), quint16(0));
|
||||
QCOMPARE(socketDevice.peerAddress(), QHostAddress());
|
||||
QCOMPARE(socketDevice.peerPort(), quint16(0));
|
||||
QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError);
|
||||
QCOMPARE(socketDevice.option(QNativeSocketEngine::NonBlockingSocketOption), -1);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::bytesAvailable() was called in QAbstractSocket::UnconnectedState");
|
||||
QCOMPARE(socketDevice.bytesAvailable(), -1);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState");
|
||||
QVERIFY(!socketDevice.hasPendingDatagrams());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::simpleConnectToIMAP()
|
||||
{
|
||||
PLATFORMSOCKETENGINE socketDevice;
|
||||
|
||||
// Initialize device
|
||||
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
|
||||
const bool isConnected = socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143);
|
||||
if (!isConnected) {
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(socketDevice.waitForWrite());
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
|
||||
}
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp());
|
||||
|
||||
// Wait for the greeting
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
|
||||
// Read the greeting
|
||||
qint64 available = socketDevice.bytesAvailable();
|
||||
QVERIFY(available > 0);
|
||||
QByteArray array;
|
||||
array.resize(available);
|
||||
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
|
||||
|
||||
// Check that the greeting is what we expect it to be
|
||||
QVERIFY2(QtNetworkSettings::compareReplyIMAP(array), array.constData());
|
||||
|
||||
// Write a logout message
|
||||
QByteArray array2 = "ZZZ LOGOUT\r\n";
|
||||
QVERIFY(socketDevice.write(array2.data(),
|
||||
array2.size()) == array2.size());
|
||||
|
||||
// Wait for the response
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
|
||||
available = socketDevice.bytesAvailable();
|
||||
QVERIFY(available > 0);
|
||||
array.resize(available);
|
||||
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
|
||||
|
||||
// Check that the greeting is what we expect it to be
|
||||
QCOMPARE(array.constData(),
|
||||
"* BYE LOGOUT received\r\n"
|
||||
"ZZZ OK Completed\r\n");
|
||||
|
||||
// Wait for the response
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
char c;
|
||||
QVERIFY(socketDevice.read(&c, sizeof(c)) == -1);
|
||||
QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError);
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::udpLoopbackTest()
|
||||
{
|
||||
PLATFORMSOCKETENGINE udpSocket;
|
||||
|
||||
// Initialize device #1
|
||||
QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket));
|
||||
QVERIFY(udpSocket.isValid());
|
||||
QVERIFY(udpSocket.socketDescriptor() != -1);
|
||||
QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol);
|
||||
QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket);
|
||||
QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState);
|
||||
|
||||
// Bind #1 to localhost
|
||||
QVERIFY(udpSocket.bind(QHostAddress("127.0.0.1"), 0));
|
||||
QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = udpSocket.localPort();
|
||||
QVERIFY(port != 0);
|
||||
|
||||
// Initialize device #2
|
||||
PLATFORMSOCKETENGINE udpSocket2;
|
||||
QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket));
|
||||
|
||||
// Connect device #2 to #1
|
||||
QVERIFY(udpSocket2.connectToHost(QHostAddress("127.0.0.1"), port));
|
||||
QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
// Write a message to #1
|
||||
QByteArray message1 = "hei der";
|
||||
QVERIFY(udpSocket2.write(message1.data(),
|
||||
message1.size()) == message1.size());
|
||||
|
||||
// Read the message from #2
|
||||
QVERIFY(udpSocket.waitForRead());
|
||||
QVERIFY(udpSocket.hasPendingDatagrams());
|
||||
qint64 available = udpSocket.pendingDatagramSize();
|
||||
QVERIFY(available > 0);
|
||||
QByteArray answer;
|
||||
answer.resize(available);
|
||||
QIpPacketHeader header;
|
||||
QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
|
||||
&header, QAbstractSocketEngine::WantDatagramSender),
|
||||
qint64(message1.size()));
|
||||
QVERIFY(header.senderAddress == QHostAddress("127.0.0.1"));
|
||||
QCOMPARE(header.senderAddress, QHostAddress("127.0.0.1"));
|
||||
QVERIFY(header.senderPort != 0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::udpIPv6LoopbackTest()
|
||||
{
|
||||
PLATFORMSOCKETENGINE udpSocket;
|
||||
|
||||
// Initialize device #1
|
||||
bool init = udpSocket.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol);
|
||||
|
||||
if (!init) {
|
||||
QCOMPARE(udpSocket.error(), QAbstractSocket::UnsupportedSocketOperationError);
|
||||
} else {
|
||||
QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv6Protocol);
|
||||
|
||||
// Bind #1 to localhost
|
||||
QVERIFY(udpSocket.bind(QHostAddress("::1"), 0));
|
||||
QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = udpSocket.localPort();
|
||||
QVERIFY(port != 0);
|
||||
|
||||
// Initialize device #2
|
||||
PLATFORMSOCKETENGINE udpSocket2;
|
||||
QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol));
|
||||
|
||||
// Connect device #2 to #1
|
||||
QVERIFY(udpSocket2.connectToHost(QHostAddress("::1"), port));
|
||||
QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
// Write a message to #1
|
||||
QByteArray message1 = "hei der";
|
||||
QVERIFY(udpSocket2.write(message1.data(),
|
||||
message1.size()) == message1.size());
|
||||
|
||||
// Read the message from #2
|
||||
QVERIFY(udpSocket.waitForRead());
|
||||
QVERIFY(udpSocket.hasPendingDatagrams());
|
||||
qint64 available = udpSocket.pendingDatagramSize();
|
||||
QVERIFY(available > 0);
|
||||
QByteArray answer;
|
||||
answer.resize(available);
|
||||
QIpPacketHeader header;
|
||||
QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
|
||||
&header, QAbstractSocketEngine::WantDatagramSender),
|
||||
qint64(message1.size()));
|
||||
QVERIFY(header.senderAddress == QHostAddress("::1"));
|
||||
QCOMPARE(header.senderAddress, QHostAddress("::1"));
|
||||
QVERIFY(header.senderPort != 0);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::broadcastTest()
|
||||
{
|
||||
#ifdef Q_OS_AIX
|
||||
QSKIP("Broadcast does not work on darko");
|
||||
#endif
|
||||
PLATFORMSOCKETENGINE broadcastSocket;
|
||||
|
||||
// Initialize a regular Udp socket
|
||||
QVERIFY(broadcastSocket.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::AnyIPProtocol));
|
||||
|
||||
// Bind to any port on all interfaces
|
||||
QVERIFY(broadcastSocket.bind(QHostAddress::Any, 0));
|
||||
QCOMPARE(broadcastSocket.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = broadcastSocket.localPort();
|
||||
QVERIFY(port > 0);
|
||||
|
||||
// Broadcast an inappropriate troll message
|
||||
QByteArray trollMessage
|
||||
= "MOOT wtf is a MOOT? talk english not your sutpiD ENGLISH.";
|
||||
qint64 written = broadcastSocket.writeDatagram(trollMessage.data(),
|
||||
trollMessage.size(),
|
||||
QIpPacketHeader(QHostAddress::Broadcast, port));
|
||||
|
||||
QVERIFY2(written != -1, qt_error_string().toLocal8Bit());
|
||||
QCOMPARE((int)written, trollMessage.size());
|
||||
|
||||
// Wait until we receive it ourselves
|
||||
#if defined(Q_OS_FREEBSD)
|
||||
QEXPECT_FAIL("", "Broadcasting to 255.255.255.255 does not work on FreeBSD", Abort);
|
||||
#endif
|
||||
QVERIFY(broadcastSocket.waitForRead());
|
||||
QVERIFY(broadcastSocket.hasPendingDatagrams());
|
||||
|
||||
qlonglong available = broadcastSocket.pendingDatagramSize();
|
||||
QByteArray response;
|
||||
response.resize(available);
|
||||
QVERIFY(broadcastSocket.readDatagram(response.data(), response.size())
|
||||
== response.size());
|
||||
QCOMPARE(response, trollMessage);
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::serverTest()
|
||||
{
|
||||
PLATFORMSOCKETENGINE server;
|
||||
|
||||
// Initialize a Tcp socket
|
||||
QVERIFY(server.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
// Bind to any port on all interfaces
|
||||
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
|
||||
QCOMPARE(server.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = server.localPort();
|
||||
|
||||
// Listen for incoming connections
|
||||
QVERIFY(server.listen(50));
|
||||
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
|
||||
|
||||
// Initialize a Tcp socket
|
||||
PLATFORMSOCKETENGINE client;
|
||||
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
|
||||
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(client.waitForWrite());
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
|
||||
}
|
||||
|
||||
// The server accepts the connection
|
||||
int socketDescriptor = server.accept();
|
||||
QVERIFY(socketDescriptor > 0);
|
||||
|
||||
// A socket device is initialized on the server side, passing the
|
||||
// socket descriptor from accept(). It's pre-connected.
|
||||
PLATFORMSOCKETENGINE serverSocket;
|
||||
QVERIFY(serverSocket.initialize(socketDescriptor));
|
||||
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
// The server socket sends a greeting to the clietn
|
||||
QByteArray greeting = "Greetings!";
|
||||
QVERIFY(serverSocket.write(greeting.data(),
|
||||
greeting.size()) == greeting.size());
|
||||
|
||||
// The client waits for the greeting to arrive
|
||||
QVERIFY(client.waitForRead());
|
||||
qint64 available = client.bytesAvailable();
|
||||
QVERIFY(available > 0);
|
||||
|
||||
// The client reads the greeting and checks that it's correct
|
||||
QByteArray response;
|
||||
response.resize(available);
|
||||
QVERIFY(client.read(response.data(),
|
||||
response.size()) == response.size());
|
||||
QCOMPARE(response, greeting);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::udpLoopbackPerformance()
|
||||
{
|
||||
PLATFORMSOCKETENGINE udpSocket;
|
||||
|
||||
// Initialize device #1
|
||||
QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket));
|
||||
QVERIFY(udpSocket.isValid());
|
||||
QVERIFY(udpSocket.socketDescriptor() != -1);
|
||||
QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol);
|
||||
QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket);
|
||||
QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState);
|
||||
|
||||
// Bind #1 to localhost
|
||||
QVERIFY(udpSocket.bind(QHostAddress("127.0.0.1"), 0));
|
||||
QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = udpSocket.localPort();
|
||||
QVERIFY(port != 0);
|
||||
|
||||
// Initialize device #2
|
||||
PLATFORMSOCKETENGINE udpSocket2;
|
||||
QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket));
|
||||
|
||||
// Connect device #2 to #1
|
||||
QVERIFY(udpSocket2.connectToHost(QHostAddress("127.0.0.1"), port));
|
||||
QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
const int messageSize = 8192;
|
||||
QByteArray message1(messageSize, '@');
|
||||
QByteArray answer(messageSize, '@');
|
||||
|
||||
QHostAddress localhost = QHostAddress::LocalHost;
|
||||
|
||||
qlonglong readBytes = 0;
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
while (timer.elapsed() < 5000) {
|
||||
udpSocket2.write(message1.data(), message1.size());
|
||||
udpSocket.waitForRead();
|
||||
while (udpSocket.hasPendingDatagrams()) {
|
||||
readBytes += (qlonglong) udpSocket.readDatagram(answer.data(),
|
||||
answer.size());
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
|
||||
readBytes / (1024.0 * 1024.0),
|
||||
timer.elapsed() / 1024.0,
|
||||
(readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::tcpLoopbackPerformance()
|
||||
{
|
||||
PLATFORMSOCKETENGINE server;
|
||||
|
||||
// Initialize a Tcp socket
|
||||
QVERIFY(server.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
// Bind to any port on all interfaces
|
||||
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
|
||||
QCOMPARE(server.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = server.localPort();
|
||||
|
||||
// Listen for incoming connections
|
||||
QVERIFY(server.listen(50));
|
||||
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
|
||||
|
||||
// Initialize a Tcp socket
|
||||
PLATFORMSOCKETENGINE client;
|
||||
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
// Connect to our server
|
||||
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(client.waitForWrite());
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
|
||||
}
|
||||
|
||||
// The server accepts the connection
|
||||
int socketDescriptor = server.accept();
|
||||
QVERIFY(socketDescriptor > 0);
|
||||
|
||||
// A socket device is initialized on the server side, passing the
|
||||
// socket descriptor from accept(). It's pre-connected.
|
||||
PLATFORMSOCKETENGINE serverSocket;
|
||||
QVERIFY(serverSocket.initialize(socketDescriptor));
|
||||
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
const int messageSize = 1024 * 256;
|
||||
QByteArray message1(messageSize, '@');
|
||||
QByteArray answer(messageSize, '@');
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
qlonglong readBytes = 0;
|
||||
while (timer.elapsed() < 5000) {
|
||||
qlonglong written = serverSocket.write(message1.data(), message1.size());
|
||||
while (written > 0) {
|
||||
client.waitForRead();
|
||||
if (client.bytesAvailable() > 0) {
|
||||
qlonglong readNow = client.read(answer.data(), answer.size());
|
||||
written -= readNow;
|
||||
readBytes += readNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
|
||||
readBytes / (1024.0 * 1024.0),
|
||||
timer.elapsed() / 1024.0,
|
||||
(readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
|
||||
}
|
||||
|
||||
#if 0 // unused
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::readWriteBufferSize()
|
||||
{
|
||||
PLATFORMSOCKETENGINE device;
|
||||
|
||||
QVERIFY(device.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
qint64 bufferSize = device.receiveBufferSize();
|
||||
QVERIFY(bufferSize != -1);
|
||||
device.setReceiveBufferSize(bufferSize + 1);
|
||||
QVERIFY(device.receiveBufferSize() > bufferSize);
|
||||
|
||||
bufferSize = device.sendBufferSize();
|
||||
QVERIFY(bufferSize != -1);
|
||||
device.setSendBufferSize(bufferSize + 1);
|
||||
QVERIFY(device.sendBufferSize() > bufferSize);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::tooManySockets()
|
||||
{
|
||||
#if defined Q_OS_WIN
|
||||
QSKIP("Certain windows machines suffocate and spend too much time in this test.");
|
||||
#endif
|
||||
QList<PLATFORMSOCKETENGINE *> sockets;
|
||||
PLATFORMSOCKETENGINE *socketLayer = 0;
|
||||
for (;;) {
|
||||
socketLayer = new PLATFORMSOCKETENGINE;
|
||||
sockets.append(socketLayer);
|
||||
|
||||
if (!socketLayer->initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol))
|
||||
break;
|
||||
}
|
||||
|
||||
QCOMPARE(socketLayer->error(), QAbstractSocket::SocketResourceError);
|
||||
|
||||
qDeleteAll(sockets);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::bind()
|
||||
{
|
||||
PLATFORMSOCKETENGINE binder;
|
||||
QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QCOMPARE(binder.bind(QHostAddress::AnyIPv4, 82), QtNetworkSettings::canBindToLowPorts());
|
||||
if (!QtNetworkSettings::canBindToLowPorts())
|
||||
QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError);
|
||||
|
||||
PLATFORMSOCKETENGINE binder2;
|
||||
QVERIFY(binder2.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QVERIFY(binder2.bind(QHostAddress::AnyIPv4, 31180));
|
||||
|
||||
PLATFORMSOCKETENGINE binder3;
|
||||
QVERIFY(binder3.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QVERIFY(!binder3.bind(QHostAddress::AnyIPv4, 31180));
|
||||
QCOMPARE(binder3.error(), QAbstractSocket::AddressInUseError);
|
||||
|
||||
if (QtNetworkSettings::hasIPv6()) {
|
||||
PLATFORMSOCKETENGINE binder;
|
||||
QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
|
||||
QCOMPARE(binder.bind(QHostAddress::AnyIPv6, 82), QtNetworkSettings::canBindToLowPorts());
|
||||
if (!QtNetworkSettings::canBindToLowPorts())
|
||||
QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError);
|
||||
|
||||
PLATFORMSOCKETENGINE binder4;
|
||||
QVERIFY(binder4.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
|
||||
QVERIFY(binder4.bind(QHostAddress::AnyIPv6, 31180));
|
||||
|
||||
PLATFORMSOCKETENGINE binder5;
|
||||
QVERIFY(binder5.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
|
||||
QVERIFY(!binder5.bind(QHostAddress::AnyIPv6, 31180));
|
||||
QCOMPARE(binder5.error(), QAbstractSocket::AddressInUseError);
|
||||
}
|
||||
|
||||
PLATFORMSOCKETENGINE binder6;
|
||||
QVERIFY(binder6.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::AnyIPProtocol));
|
||||
QVERIFY(binder6.bind(QHostAddress::Any, 31181));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::networkError()
|
||||
{
|
||||
PLATFORMSOCKETENGINE client;
|
||||
|
||||
QVERIFY(client.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
|
||||
const bool isConnected = client.connectToHost(QtNetworkSettings::imapServerIp(), 143);
|
||||
if (!isConnected) {
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(client.waitForWrite());
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
|
||||
}
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
// An unexpected network error!
|
||||
#if defined(Q_OS_WIN)
|
||||
// could use shutdown to produce different errors
|
||||
::closesocket(client.socketDescriptor());
|
||||
#else
|
||||
::close(client.socketDescriptor());
|
||||
#endif
|
||||
|
||||
QVERIFY(client.read(0, 0) == -1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::setSocketDescriptor()
|
||||
{
|
||||
PLATFORMSOCKETENGINE socket1;
|
||||
QVERIFY(socket1.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
PLATFORMSOCKETENGINE socket2;
|
||||
QVERIFY(socket2.initialize(socket1.socketDescriptor()));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::invalidSend()
|
||||
{
|
||||
PLATFORMSOCKETENGINE socket;
|
||||
QVERIFY(socket.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::writeDatagram() was called"
|
||||
" not in QAbstractSocket::BoundState or QAbstractSocket::ConnectedState");
|
||||
QCOMPARE(socket.writeDatagram("hei", 3, QIpPacketHeader(QHostAddress::LocalHost, 143)),
|
||||
(qlonglong) -1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_PlatformSocketEngine::receiveUrgentData()
|
||||
{
|
||||
PLATFORMSOCKETENGINE server;
|
||||
|
||||
QVERIFY(server.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
// Bind to any port on all interfaces
|
||||
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
|
||||
QCOMPARE(server.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = server.localPort();
|
||||
|
||||
QVERIFY(server.listen(50));
|
||||
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
|
||||
|
||||
PLATFORMSOCKETENGINE client;
|
||||
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(client.waitForWrite());
|
||||
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
|
||||
}
|
||||
|
||||
int socketDescriptor = server.accept();
|
||||
QVERIFY(socketDescriptor > 0);
|
||||
|
||||
PLATFORMSOCKETENGINE serverSocket;
|
||||
QVERIFY(serverSocket.initialize(socketDescriptor));
|
||||
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
char msg;
|
||||
int available;
|
||||
QByteArray response;
|
||||
|
||||
// Native OOB data test doesn't work on HP-UX or WinCE
|
||||
#if !defined(Q_OS_HPUX)
|
||||
// The server sends an urgent message
|
||||
msg = 'Q';
|
||||
QCOMPARE(int(::send(socketDescriptor, &msg, sizeof(msg), MSG_OOB)), 1);
|
||||
|
||||
// The client receives the urgent message
|
||||
QVERIFY(client.waitForRead());
|
||||
available = client.bytesAvailable();
|
||||
QCOMPARE(available, 1);
|
||||
response.resize(available);
|
||||
QCOMPARE(client.read(response.data(), response.size()), qint64(1));
|
||||
QCOMPARE(response.at(0), msg);
|
||||
|
||||
// The client sends an urgent message
|
||||
msg = 'T';
|
||||
int clientDescriptor = client.socketDescriptor();
|
||||
QCOMPARE(int(::send(clientDescriptor, &msg, sizeof(msg), MSG_OOB)), 1);
|
||||
|
||||
// The server receives the urgent message
|
||||
QVERIFY(serverSocket.waitForRead());
|
||||
available = serverSocket.bytesAvailable();
|
||||
QCOMPARE(available, 1);
|
||||
response.resize(available);
|
||||
QCOMPARE(serverSocket.read(response.data(), response.size()), qint64(1));
|
||||
QCOMPARE(response.at(0), msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_PlatformSocketEngine)
|
||||
#include "tst_platformsocketengine.moc"
|
13
tests/auto/network/socket/qabstractsocket/CMakeLists.txt
Normal file
13
tests/auto/network/socket/qabstractsocket/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qabstractsocket Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qabstractsocket
|
||||
SOURCES
|
||||
tst_qabstractsocket.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
@ -0,0 +1,68 @@
|
||||
// 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 <qabstractsocket.h>
|
||||
|
||||
class tst_QAbstractSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QAbstractSocket();
|
||||
virtual ~tst_QAbstractSocket();
|
||||
|
||||
private slots:
|
||||
void getSetCheck();
|
||||
};
|
||||
|
||||
tst_QAbstractSocket::tst_QAbstractSocket()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QAbstractSocket::~tst_QAbstractSocket()
|
||||
{
|
||||
}
|
||||
|
||||
class MyAbstractSocket : public QAbstractSocket
|
||||
{
|
||||
public:
|
||||
MyAbstractSocket() : QAbstractSocket(QAbstractSocket::TcpSocket, 0) {}
|
||||
void setLocalPort(quint16 port) { QAbstractSocket::setLocalPort(port); }
|
||||
void setPeerPort(quint16 port) { QAbstractSocket::setPeerPort(port); }
|
||||
};
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QAbstractSocket::getSetCheck()
|
||||
{
|
||||
MyAbstractSocket obj1;
|
||||
// qint64 QAbstractSocket::readBufferSize()
|
||||
// void QAbstractSocket::setReadBufferSize(qint64)
|
||||
obj1.setReadBufferSize(qint64(0));
|
||||
QCOMPARE(qint64(0), obj1.readBufferSize());
|
||||
obj1.setReadBufferSize((Q_INT64_C(-9223372036854775807) - 1));
|
||||
QCOMPARE((Q_INT64_C(-9223372036854775807) - 1), obj1.readBufferSize());
|
||||
obj1.setReadBufferSize(Q_INT64_C(9223372036854775807));
|
||||
QCOMPARE(Q_INT64_C(9223372036854775807), obj1.readBufferSize());
|
||||
|
||||
// quint16 QAbstractSocket::localPort()
|
||||
// void QAbstractSocket::setLocalPort(quint16)
|
||||
obj1.setLocalPort(quint16(0));
|
||||
QCOMPARE(quint16(0), obj1.localPort());
|
||||
obj1.setLocalPort(quint16(0xffff));
|
||||
QCOMPARE(quint16(0xffff), obj1.localPort());
|
||||
|
||||
// quint16 QAbstractSocket::peerPort()
|
||||
// void QAbstractSocket::setPeerPort(quint16)
|
||||
obj1.setPeerPort(quint16(0));
|
||||
QCOMPARE(quint16(0), obj1.peerPort());
|
||||
obj1.setPeerPort(quint16(0xffff));
|
||||
QCOMPARE(quint16(0xffff), obj1.peerPort());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QAbstractSocket)
|
||||
#include "tst_qabstractsocket.moc"
|
5
tests/auto/network/socket/qhttpsocketengine/BLACKLIST
Normal file
5
tests/auto/network/socket/qhttpsocketengine/BLACKLIST
Normal file
@ -0,0 +1,5 @@
|
||||
[downloadBigFile]
|
||||
windows-10 msvc-2015
|
||||
windows-7sp1
|
||||
[ensureEofTriggersNotification]
|
||||
windows
|
29
tests/auto/network/socket/qhttpsocketengine/CMakeLists.txt
Normal file
29
tests/auto/network/socket/qhttpsocketengine/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
## tst_qhttpsocketengine Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qhttpsocketengine
|
||||
SOURCES
|
||||
tst_qhttpsocketengine.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::NetworkPrivate
|
||||
QT_TEST_SERVER_LIST "squid" "danted" "cyrus" "apache2"
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
# QT_TEST_SERVER_LIST = "squid" "danted" "cyrus" "apache2"
|
||||
|
||||
qt_internal_extend_target(tst_qhttpsocketengine CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
@ -0,0 +1,745 @@
|
||||
// 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 <QtCore/QQueue>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <private/qhttpsocketengine_p.h>
|
||||
#include <qhostinfo.h>
|
||||
#include <qhostaddress.h>
|
||||
#include <qtcpsocket.h>
|
||||
#include <qdebug.h>
|
||||
#include <qelapsedtimer.h>
|
||||
#include <qtcpserver.h>
|
||||
|
||||
#include "../../../network-settings.h"
|
||||
|
||||
class tst_QHttpSocketEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void init();
|
||||
void construction();
|
||||
void errorTest_data();
|
||||
void errorTest();
|
||||
void simpleConnectToIMAP();
|
||||
void simpleErrorsAndStates();
|
||||
|
||||
void tcpSocketBlockingTest();
|
||||
void tcpSocketNonBlockingTest();
|
||||
void downloadBigFile();
|
||||
// void tcpLoopbackPerformance();
|
||||
void passwordAuth();
|
||||
void ensureEofTriggersNotification();
|
||||
|
||||
protected slots:
|
||||
void tcpSocketNonBlocking_hostFound();
|
||||
void tcpSocketNonBlocking_connected();
|
||||
void tcpSocketNonBlocking_closed();
|
||||
void tcpSocketNonBlocking_readyRead();
|
||||
void tcpSocketNonBlocking_bytesWritten(qint64);
|
||||
void exitLoopSlot();
|
||||
void downloadBigFileSlot();
|
||||
|
||||
private:
|
||||
QTcpSocket *tcpSocketNonBlocking_socket;
|
||||
QStringList tcpSocketNonBlocking_data;
|
||||
qint64 tcpSocketNonBlocking_totalWritten;
|
||||
QTcpSocket *tmpSocket;
|
||||
qint64 bytesAvailable;
|
||||
};
|
||||
|
||||
class MiniHttpServer: public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
QTcpSocket *client;
|
||||
QList<QByteArray> dataToTransmit;
|
||||
|
||||
public:
|
||||
QByteArray receivedData;
|
||||
|
||||
MiniHttpServer(const QList<QByteArray> &data) : client(0), dataToTransmit(data)
|
||||
{
|
||||
listen();
|
||||
connect(this, SIGNAL(newConnection()), this, SLOT(doAccept()));
|
||||
}
|
||||
|
||||
public slots:
|
||||
void doAccept()
|
||||
{
|
||||
client = nextPendingConnection();
|
||||
connect(client, SIGNAL(readyRead()), this, SLOT(sendData()));
|
||||
}
|
||||
|
||||
void sendData()
|
||||
{
|
||||
receivedData += client->readAll();
|
||||
int idx = client->property("dataTransmitionIdx").toInt();
|
||||
if (receivedData.contains("\r\n\r\n") ||
|
||||
receivedData.contains("\n\n")) {
|
||||
if (idx < dataToTransmit.size())
|
||||
client->write(dataToTransmit.at(idx++));
|
||||
if (idx == dataToTransmit.size()) {
|
||||
client->disconnectFromHost();
|
||||
disconnect(client, 0, this, 0);
|
||||
client = 0;
|
||||
} else {
|
||||
client->setProperty("dataTransmitionIdx", idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QHttpSocketEngine::initTestCase()
|
||||
{
|
||||
#ifdef QT_TEST_SERVER
|
||||
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128));
|
||||
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080));
|
||||
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80));
|
||||
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143));
|
||||
#else
|
||||
if (!QtNetworkSettings::verifyTestNetworkSettings())
|
||||
QSKIP("No network test server available");
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::init()
|
||||
{
|
||||
tmpSocket = 0;
|
||||
bytesAvailable = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_QHttpSocketEngine::construction()
|
||||
{
|
||||
QHttpSocketEngine socketDevice;
|
||||
|
||||
QVERIFY(!socketDevice.isValid());
|
||||
|
||||
// Initialize device
|
||||
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QVERIFY(socketDevice.isValid());
|
||||
QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol);
|
||||
QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket);
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
// QVERIFY(socketDevice.socketDescriptor() != -1);
|
||||
QCOMPARE(socketDevice.localAddress(), QHostAddress());
|
||||
QCOMPARE(socketDevice.localPort(), quint16(0));
|
||||
QCOMPARE(socketDevice.peerAddress(), QHostAddress());
|
||||
QCOMPARE(socketDevice.peerPort(), quint16(0));
|
||||
QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError);
|
||||
|
||||
//QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::bytesAvailable() was called in QAbstractSocket::UnconnectedState");
|
||||
QCOMPARE(socketDevice.bytesAvailable(), 0);
|
||||
|
||||
//QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState");
|
||||
QVERIFY(!socketDevice.hasPendingDatagrams());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_QHttpSocketEngine::errorTest_data()
|
||||
{
|
||||
QTest::addColumn<QString>("hostname");
|
||||
QTest::addColumn<int>("port");
|
||||
QTest::addColumn<QString>("username");
|
||||
QTest::addColumn<QString>("response");
|
||||
QTest::addColumn<int>("expectedError");
|
||||
|
||||
QQueue<QByteArray> responses;
|
||||
QTest::newRow("proxy-host-not-found") << "this-host-does-not-exist." << 1080 << QString()
|
||||
<< QString()
|
||||
<< int(QAbstractSocket::ProxyNotFoundError);
|
||||
QTest::newRow("proxy-connection-refused") << QtNetworkSettings::socksProxyServerName() << 2 << QString()
|
||||
<< QString()
|
||||
<< int(QAbstractSocket::ProxyConnectionRefusedError);
|
||||
|
||||
QTest::newRow("garbage1") << QString() << 0 << QString()
|
||||
<< "This is not HTTP\r\n\r\n"
|
||||
<< int(QAbstractSocket::ProxyProtocolError);
|
||||
|
||||
QTest::newRow("garbage2") << QString() << 0 << QString()
|
||||
<< "This is not HTTP"
|
||||
<< int(QAbstractSocket::ProxyProtocolError);
|
||||
|
||||
QTest::newRow("garbage3") << QString() << 0 << QString()
|
||||
<< ""
|
||||
<< int(QAbstractSocket::ProxyConnectionClosedError);
|
||||
|
||||
QTest::newRow("forbidden") << QString() << 0 << QString()
|
||||
<< "HTTP/1.0 403 Forbidden\r\n\r\n"
|
||||
<< int(QAbstractSocket::SocketAccessError);
|
||||
|
||||
QTest::newRow("method-not-allowed") << QString() << 0 << QString()
|
||||
<< "HTTP/1.0 405 Method Not Allowed\r\n\r\n"
|
||||
<< int(QAbstractSocket::SocketAccessError);
|
||||
|
||||
QTest::newRow("proxy-authentication-too-short")
|
||||
<< QString() << 0 << "foo"
|
||||
<< "HTTP/1.0 407 Proxy Authentication Required\r\n\r\n"
|
||||
<< int(QAbstractSocket::ProxyProtocolError);
|
||||
|
||||
QTest::newRow("proxy-authentication-invalid-method")
|
||||
<< QString() << 0 << "foo"
|
||||
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
|
||||
"Proxy-Authenticate: Frobnicator\r\n\r\n"
|
||||
<< int(QAbstractSocket::ProxyProtocolError);
|
||||
|
||||
QTest::newRow("proxy-authentication-required")
|
||||
<< QString() << 0 << "foo"
|
||||
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
|
||||
"Proxy-Connection: close\r\n"
|
||||
"Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
|
||||
<< int(QAbstractSocket::ProxyAuthenticationRequiredError);
|
||||
|
||||
QTest::newRow("proxy-authentication-required2")
|
||||
<< QString() << 0 << "foo"
|
||||
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
|
||||
"Proxy-Connection: keep-alive\r\n"
|
||||
"Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
|
||||
"\1"
|
||||
"HTTP/1.0 407 Proxy Authentication Required\r\n"
|
||||
"Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
|
||||
<< int(QAbstractSocket::ProxyAuthenticationRequiredError);
|
||||
|
||||
QTest::newRow("proxy-authentication-required-noclose")
|
||||
<< QString() << 0 << "foo"
|
||||
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
|
||||
"Proxy-Authenticate: Basic\r\n"
|
||||
"\r\n"
|
||||
<< int(QAbstractSocket::ProxyAuthenticationRequiredError);
|
||||
|
||||
QTest::newRow("connection-refused") << QString() << 0 << QString()
|
||||
<< "HTTP/1.0 503 Service Unavailable\r\n\r\n"
|
||||
<< int(QAbstractSocket::ConnectionRefusedError);
|
||||
|
||||
QTest::newRow("host-not-found") << QString() << 0 << QString()
|
||||
<< "HTTP/1.0 404 Not Found\r\n\r\n"
|
||||
<< int(QAbstractSocket::HostNotFoundError);
|
||||
|
||||
QTest::newRow("weird-http-reply") << QString() << 0 << QString()
|
||||
<< "HTTP/1.0 206 Partial Content\r\n\r\n"
|
||||
<< int(QAbstractSocket::ProxyProtocolError);
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::errorTest()
|
||||
{
|
||||
QFETCH(QString, hostname);
|
||||
QFETCH(int, port);
|
||||
QFETCH(QString, username);
|
||||
QFETCH(QString, response);
|
||||
QFETCH(int, expectedError);
|
||||
|
||||
MiniHttpServer server(response.toLatin1().split('\1'));
|
||||
|
||||
if (hostname.isEmpty()) {
|
||||
hostname = "127.0.0.1";
|
||||
port = server.serverPort();
|
||||
}
|
||||
QTcpSocket socket;
|
||||
socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, hostname, port, username, username));
|
||||
socket.connectToHost("0.1.2.3", 12345);
|
||||
|
||||
connect(&socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
|
||||
&QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(int(socket.error()), expectedError);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_QHttpSocketEngine::simpleConnectToIMAP()
|
||||
{
|
||||
QHttpSocketEngine socketDevice;
|
||||
|
||||
// Initialize device
|
||||
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
|
||||
socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128));
|
||||
QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143));
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(socketDevice.waitForWrite());
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp());
|
||||
QVERIFY(!socketDevice.localAddress().isNull());
|
||||
QVERIFY(socketDevice.localPort() > 0);
|
||||
|
||||
// Wait for the greeting
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
|
||||
// Read the greeting
|
||||
qint64 available = int(socketDevice.bytesAvailable());
|
||||
QVERIFY(available > 0);
|
||||
QByteArray array;
|
||||
array.resize(int(available));
|
||||
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
|
||||
|
||||
// Check that the greeting is what we expect it to be
|
||||
QVERIFY2(QtNetworkSettings::compareReplyIMAP(array), array.constData());
|
||||
|
||||
|
||||
// Write a logout message
|
||||
QByteArray array2 = "XXXX LOGOUT\r\n";
|
||||
QVERIFY(socketDevice.write(array2.data(),
|
||||
array2.size()) == array2.size());
|
||||
|
||||
// Wait for the response
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
|
||||
available = int(socketDevice.bytesAvailable());
|
||||
QVERIFY(available > 0);
|
||||
array.resize(int(available));
|
||||
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
|
||||
|
||||
// Check that the greeting is what we expect it to be
|
||||
QCOMPARE(array.constData(), "* BYE LOGOUT received\r\nXXXX OK Completed\r\n");
|
||||
|
||||
// Wait for the response
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
char c;
|
||||
QCOMPARE(socketDevice.read(&c, sizeof(c)), qint64(-1));
|
||||
QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError);
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_QHttpSocketEngine::simpleErrorsAndStates()
|
||||
{
|
||||
{
|
||||
QHttpSocketEngine socketDevice;
|
||||
|
||||
// Initialize device
|
||||
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
|
||||
socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128));
|
||||
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::socksProxyServerName()), 8088));
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
|
||||
if (socketDevice.waitForWrite(30000)) {
|
||||
QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState ||
|
||||
socketDevice.state() == QAbstractSocket::UnconnectedState);
|
||||
} else {
|
||||
QCOMPARE(socketDevice.error(), QAbstractSocket::SocketTimeoutError);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
//---------------------------------------------------------------------------
|
||||
void tst_QHttpSocketEngine::tcpLoopbackPerformance()
|
||||
{
|
||||
QTcpServer server;
|
||||
|
||||
// Bind to any port on all interfaces
|
||||
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
|
||||
QCOMPARE(server.state(), QAbstractSocket::BoundState);
|
||||
quint16 port = server.localPort();
|
||||
|
||||
// Listen for incoming connections
|
||||
QVERIFY(server.listen());
|
||||
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
|
||||
|
||||
// Initialize a Tcp socket
|
||||
QHttpSocketEngine client;
|
||||
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
|
||||
|
||||
client.setProxy(QHostAddress("80.232.37.158"), 1081);
|
||||
|
||||
// Connect to our server
|
||||
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
|
||||
QVERIFY(client.waitForWrite());
|
||||
QVERIFY(client.connectToHost(QHostAddress("127.0.0.1"), port));
|
||||
}
|
||||
|
||||
// The server accepts the connectio
|
||||
int socketDescriptor = server.accept();
|
||||
QVERIFY(socketDescriptor > 0);
|
||||
|
||||
// A socket device is initialized on the server side, passing the
|
||||
// socket descriptor from accept(). It's pre-connected.
|
||||
QSocketLayer serverSocket;
|
||||
QVERIFY(serverSocket.initialize(socketDescriptor));
|
||||
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
const int messageSize = 1024 * 256;
|
||||
QByteArray message1(messageSize, '@');
|
||||
QByteArray answer(messageSize, '@');
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
qlonglong readBytes = 0;
|
||||
while (timer.elapsed() < 30000) {
|
||||
qlonglong written = serverSocket.write(message1.data(), message1.size());
|
||||
while (written > 0) {
|
||||
client.waitForRead();
|
||||
if (client.bytesAvailable() > 0) {
|
||||
qlonglong readNow = client.read(answer.data(), answer.size());
|
||||
written -= readNow;
|
||||
readBytes += readNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
|
||||
readBytes / (1024.0 * 1024.0),
|
||||
timer.elapsed() / 1024.0,
|
||||
(readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketBlockingTest()
|
||||
{
|
||||
QHttpSocketEngineHandler http;
|
||||
|
||||
QTcpSocket socket;
|
||||
|
||||
// Connect
|
||||
socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
|
||||
QVERIFY(socket.waitForConnected());
|
||||
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
|
||||
|
||||
// Read greeting
|
||||
QVERIFY(socket.waitForReadyRead(30000));
|
||||
QString s = socket.readLine();
|
||||
QVERIFY2(QtNetworkSettings::compareReplyIMAP(s.toLatin1()), qPrintable(s));
|
||||
|
||||
// Write NOOP
|
||||
QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8);
|
||||
|
||||
if (!socket.canReadLine())
|
||||
QVERIFY(socket.waitForReadyRead(30000));
|
||||
|
||||
// Read response
|
||||
s = socket.readLine();
|
||||
QCOMPARE(s.toLatin1().constData(), "1 OK Completed\r\n");
|
||||
|
||||
// Write LOGOUT
|
||||
QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10);
|
||||
|
||||
if (!socket.canReadLine())
|
||||
QVERIFY(socket.waitForReadyRead(30000));
|
||||
|
||||
// Read two lines of respose
|
||||
s = socket.readLine();
|
||||
QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n");
|
||||
|
||||
if (!socket.canReadLine())
|
||||
QVERIFY(socket.waitForReadyRead(30000));
|
||||
|
||||
s = socket.readLine();
|
||||
QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n");
|
||||
|
||||
// Close the socket
|
||||
socket.close();
|
||||
|
||||
// Check that it's closed
|
||||
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketNonBlockingTest()
|
||||
{
|
||||
QHttpSocketEngineHandler http;
|
||||
|
||||
QTcpSocket socket;
|
||||
connect(&socket, SIGNAL(hostFound()), SLOT(tcpSocketNonBlocking_hostFound()));
|
||||
connect(&socket, SIGNAL(connected()), SLOT(tcpSocketNonBlocking_connected()));
|
||||
connect(&socket, SIGNAL(disconnected()), SLOT(tcpSocketNonBlocking_closed()));
|
||||
connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(tcpSocketNonBlocking_bytesWritten(qint64)));
|
||||
connect(&socket, SIGNAL(readyRead()), SLOT(tcpSocketNonBlocking_readyRead()));
|
||||
tcpSocketNonBlocking_socket = &socket;
|
||||
|
||||
// Connect
|
||||
socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
|
||||
QVERIFY(socket.state() == QTcpSocket::HostLookupState ||
|
||||
socket.state() == QTcpSocket::ConnectingState);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
|
||||
if (socket.state() == QTcpSocket::ConnectingState) {
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
}
|
||||
|
||||
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
|
||||
// Read greeting
|
||||
QVERIFY(!tcpSocketNonBlocking_data.isEmpty());
|
||||
QByteArray data = tcpSocketNonBlocking_data.at(0).toLatin1();
|
||||
QVERIFY2(QtNetworkSettings::compareReplyIMAP(data), data.constData());
|
||||
|
||||
|
||||
tcpSocketNonBlocking_data.clear();
|
||||
|
||||
tcpSocketNonBlocking_totalWritten = 0;
|
||||
|
||||
// Write NOOP
|
||||
QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8);
|
||||
|
||||
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
|
||||
QCOMPARE(tcpSocketNonBlocking_totalWritten, 8);
|
||||
|
||||
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
|
||||
|
||||
// Read response
|
||||
QVERIFY(!tcpSocketNonBlocking_data.isEmpty());
|
||||
QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(), "1 OK Completed\r\n");
|
||||
tcpSocketNonBlocking_data.clear();
|
||||
|
||||
|
||||
tcpSocketNonBlocking_totalWritten = 0;
|
||||
|
||||
// Write LOGOUT
|
||||
QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
|
||||
QCOMPARE(tcpSocketNonBlocking_totalWritten, 10);
|
||||
|
||||
// Wait for greeting
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout()) {
|
||||
QFAIL("Timed out");
|
||||
}
|
||||
|
||||
// Read two lines of respose
|
||||
QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(), "* BYE LOGOUT received\r\n");
|
||||
QCOMPARE(tcpSocketNonBlocking_data.at(1).toLatin1().constData(), "2 OK Completed\r\n");
|
||||
tcpSocketNonBlocking_data.clear();
|
||||
|
||||
// Close the socket
|
||||
socket.close();
|
||||
|
||||
// Check that it's closed
|
||||
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketNonBlocking_hostFound()
|
||||
{
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketNonBlocking_connected()
|
||||
{
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketNonBlocking_readyRead()
|
||||
{
|
||||
while (tcpSocketNonBlocking_socket->canReadLine())
|
||||
tcpSocketNonBlocking_data.append(tcpSocketNonBlocking_socket->readLine());
|
||||
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketNonBlocking_bytesWritten(qint64 written)
|
||||
{
|
||||
tcpSocketNonBlocking_totalWritten += written;
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::tcpSocketNonBlocking_closed()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
void tst_QHttpSocketEngine::downloadBigFile()
|
||||
{
|
||||
QHttpSocketEngineHandler http;
|
||||
|
||||
if (tmpSocket)
|
||||
delete tmpSocket;
|
||||
tmpSocket = new QTcpSocket;
|
||||
|
||||
connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
|
||||
connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot()));
|
||||
|
||||
tmpSocket->connectToHost(QtNetworkSettings::httpServerName(), 80);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(30);
|
||||
if (QTestEventLoop::instance().timeout())
|
||||
QFAIL("Network operation timed out");
|
||||
|
||||
QByteArray hostName = QtNetworkSettings::httpServerName().toLatin1();
|
||||
QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
|
||||
QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0);
|
||||
QVERIFY(tmpSocket->write("Host: ") > 0);
|
||||
QVERIFY(tmpSocket->write(hostName.data()) > 0);
|
||||
QVERIFY(tmpSocket->write("\r\n") > 0);
|
||||
QVERIFY(tmpSocket->write("\r\n") > 0);
|
||||
|
||||
bytesAvailable = 0;
|
||||
|
||||
QElapsedTimer stopWatch;
|
||||
stopWatch.start();
|
||||
|
||||
QTestEventLoop::instance().enterLoop(60);
|
||||
if (QTestEventLoop::instance().timeout())
|
||||
QFAIL("Network operation timed out");
|
||||
|
||||
QVERIFY(bytesAvailable >= 10000000);
|
||||
|
||||
QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
|
||||
bytesAvailable / (1024.0 * 1024.0),
|
||||
stopWatch.elapsed() / 1024.0,
|
||||
(bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
|
||||
|
||||
delete tmpSocket;
|
||||
tmpSocket = 0;
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::exitLoopSlot()
|
||||
{
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
|
||||
void tst_QHttpSocketEngine::downloadBigFileSlot()
|
||||
{
|
||||
bytesAvailable += tmpSocket->readAll().size();
|
||||
if (bytesAvailable >= 10000000)
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
|
||||
void tst_QHttpSocketEngine::passwordAuth()
|
||||
{
|
||||
QHttpSocketEngine socketDevice;
|
||||
|
||||
// Initialize device
|
||||
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
|
||||
socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128, "qsockstest", "password"));
|
||||
|
||||
QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143));
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
|
||||
QVERIFY(socketDevice.waitForWrite());
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp());
|
||||
|
||||
// Wait for the greeting
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
|
||||
// Read the greeting
|
||||
qint64 available = socketDevice.bytesAvailable();
|
||||
QVERIFY(available > 0);
|
||||
QByteArray array;
|
||||
array.resize(available);
|
||||
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
|
||||
|
||||
// Check that the greeting is what we expect it to be
|
||||
QVERIFY2(QtNetworkSettings::compareReplyIMAP(array), array.constData());
|
||||
|
||||
|
||||
// Write a logout message
|
||||
QByteArray array2 = "XXXX LOGOUT\r\n";
|
||||
QVERIFY(socketDevice.write(array2.data(),
|
||||
array2.size()) == array2.size());
|
||||
|
||||
// Wait for the response
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
|
||||
available = socketDevice.bytesAvailable();
|
||||
QVERIFY(available > 0);
|
||||
array.resize(available);
|
||||
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
|
||||
|
||||
// Check that the greeting is what we expect it to be
|
||||
QCOMPARE(array.constData(), "* BYE LOGOUT received\r\nXXXX OK Completed\r\n");
|
||||
|
||||
// Wait for the response
|
||||
QVERIFY(socketDevice.waitForRead());
|
||||
char c;
|
||||
QVERIFY(socketDevice.read(&c, sizeof(c)) == -1);
|
||||
QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError);
|
||||
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
void tst_QHttpSocketEngine::ensureEofTriggersNotification()
|
||||
{
|
||||
QList<QByteArray> serverData;
|
||||
// Set the handshake and server response data
|
||||
serverData << "HTTP/1.0 200 Connection established\r\n\r\n" << "0";
|
||||
MiniHttpServer server(serverData);
|
||||
|
||||
QTcpSocket socket;
|
||||
connect(&socket, SIGNAL(connected()), SLOT(exitLoopSlot()));
|
||||
socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, server.serverAddress().toString(),
|
||||
server.serverPort()));
|
||||
socket.connectToHost("0.1.2.3", 12345);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
if (QTestEventLoop::instance().timeout())
|
||||
QFAIL("Connect timed out");
|
||||
|
||||
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
|
||||
// Disable read notification on server response
|
||||
socket.setReadBufferSize(1);
|
||||
socket.putChar(0);
|
||||
|
||||
// Wait for the response
|
||||
connect(&socket, SIGNAL(readyRead()), SLOT(exitLoopSlot()));
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
if (QTestEventLoop::instance().timeout())
|
||||
QFAIL("Read timed out");
|
||||
|
||||
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
|
||||
QCOMPARE(socket.bytesAvailable(), 1);
|
||||
// Trigger a read notification
|
||||
socket.readAll();
|
||||
// Check for pending EOF at input
|
||||
QCOMPARE(socket.bytesAvailable(), 0);
|
||||
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
|
||||
|
||||
// Try to read EOF
|
||||
connect(&socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
if (QTestEventLoop::instance().timeout())
|
||||
QFAIL("Disconnect timed out");
|
||||
|
||||
// Check that it's closed
|
||||
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHttpSocketEngine)
|
||||
#include "tst_qhttpsocketengine.moc"
|
10
tests/auto/network/socket/qlocalsocket/BLACKLIST
Normal file
10
tests/auto/network/socket/qlocalsocket/BLACKLIST
Normal file
@ -0,0 +1,10 @@
|
||||
# QTBUG-87387
|
||||
[fullPath]
|
||||
android
|
||||
[processConnection]
|
||||
android
|
||||
windows
|
||||
[verifySocketOptions]
|
||||
android
|
||||
[threadedConnection]
|
||||
windows
|
15
tests/auto/network/socket/qlocalsocket/CMakeLists.txt
Normal file
15
tests/auto/network/socket/qlocalsocket/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# add_subdirectory(test) # special case remove
|
||||
add_subdirectory(socketprocess)
|
||||
qt_internal_add_test(tst_qlocalsocket
|
||||
SOURCES
|
||||
tst_qlocalsocket.cpp
|
||||
DEFINES
|
||||
QLOCALSERVER_DEBUG
|
||||
QLOCALSOCKET_DEBUG
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
||||
add_dependencies(tst_qlocalsocket socketprocess)
|
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## socketprocess Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_executable(socketprocess
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
Qt::Test
|
||||
)
|
119
tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp
Normal file
119
tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
// 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 <qcoreapplication.h>
|
||||
#include <qelapsedtimer.h>
|
||||
#include <qeventloop.h>
|
||||
#include <qlocalsocket.h>
|
||||
#include <qlocalserver.h>
|
||||
#include <qtimer.h>
|
||||
|
||||
const QString serverName = QStringLiteral("qlocalsocket_autotest");
|
||||
const QByteArray testData("test");
|
||||
|
||||
bool runServer(int numberOfConnections)
|
||||
{
|
||||
QLocalServer *server = new QLocalServer(qApp);
|
||||
if (!server->removeServer(serverName)) {
|
||||
fprintf(stderr, "server: cannot remove server: %s\n", qPrintable(server->errorString()));
|
||||
return false;
|
||||
}
|
||||
printf("server: listen on \"%s\"\n", qPrintable(serverName));
|
||||
if (!server->listen(serverName)) {
|
||||
fprintf(stderr, "server: listen failed: %s\n", qPrintable(server->errorString()));
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i <= numberOfConnections; ++i) {
|
||||
printf("server: wait for connection %d\n", i);
|
||||
if (!server->waitForNewConnection(30000)) {
|
||||
fprintf(stderr, "server: waitForNewConnection failed: %s\n",
|
||||
qPrintable(server->errorString()));
|
||||
return false;
|
||||
}
|
||||
QLocalSocket *socket = server->nextPendingConnection();
|
||||
printf("server: writing \"%s\"\n", testData.data());
|
||||
socket->write(testData);
|
||||
if (!socket->waitForBytesWritten()) {
|
||||
fprintf(stderr, "server: waitForBytesWritten failed: %s\n",
|
||||
qPrintable(socket->errorString()));
|
||||
return false;
|
||||
}
|
||||
printf("server: data written\n");
|
||||
if (socket->error() != QLocalSocket::UnknownSocketError) {
|
||||
fprintf(stderr, "server: socket error %d\n", socket->error());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool runClient()
|
||||
{
|
||||
QLocalSocket socket;
|
||||
printf("client: connecting to \"%s\"\n", qPrintable(serverName));
|
||||
QElapsedTimer connectTimer;
|
||||
connectTimer.start();
|
||||
forever {
|
||||
socket.connectToServer(serverName, QLocalSocket::ReadWrite);
|
||||
if (socket.waitForConnected())
|
||||
break;
|
||||
if (socket.error() == QLocalSocket::ServerNotFoundError
|
||||
|| socket.error() == QLocalSocket::ConnectionRefusedError) {
|
||||
if (connectTimer.elapsed() > 5000) {
|
||||
fprintf(stderr, "client: server not found or connection refused. Giving up.\n");
|
||||
return false;
|
||||
}
|
||||
printf("client: server not found. Trying again...\n");
|
||||
QEventLoop eventLoop;
|
||||
QTimer::singleShot(500, &eventLoop, SLOT(quit()));
|
||||
eventLoop.exec();
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "client: waitForConnected failed: %s\n",
|
||||
qPrintable(socket.errorString()));
|
||||
return false;
|
||||
}
|
||||
printf("client: connected\n");
|
||||
if (!socket.waitForReadyRead()) {
|
||||
fprintf(stderr, "client: waitForReadyRead failed: %s\n",
|
||||
qPrintable(socket.errorString()));
|
||||
return false;
|
||||
}
|
||||
printf("client: data is available for reading\n");
|
||||
const QByteArray data = socket.readLine();
|
||||
printf("client: received \"%s\"\n", data.data());
|
||||
if (data != testData) {
|
||||
fprintf(stderr, "client: received unexpected data\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
if (argc < 2)
|
||||
return EXIT_FAILURE;
|
||||
if (strcmp(argv[1], "--server") == 0) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "--server needs the number of incoming connections\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
bool ok;
|
||||
int n = QByteArray(argv[2]).toInt(&ok);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Cannot convert %s to a number.\n", argv[2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (!runServer(n))
|
||||
return EXIT_FAILURE;
|
||||
} else if (strcmp(argv[1], "--client") == 0) {
|
||||
if (!runClient())
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
fprintf(stderr, "unknown command line option: %s\n", argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
1822
tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
Normal file
1822
tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
Normal file
File diff suppressed because it is too large
Load Diff
13
tests/auto/network/socket/qsctpsocket/CMakeLists.txt
Normal file
13
tests/auto/network/socket/qsctpsocket/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qsctpsocket Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qsctpsocket
|
||||
SOURCES
|
||||
tst_qsctpsocket.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
458
tests/auto/network/socket/qsctpsocket/tst_qsctpsocket.cpp
Normal file
458
tests/auto/network/socket/qsctpsocket/tst_qsctpsocket.cpp
Normal file
@ -0,0 +1,458 @@
|
||||
// Copyright (C) 2016 Alex Trotsenko <alex1973tr@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QTest>
|
||||
#include <QDebug>
|
||||
#include <QTestEventLoop>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QHostAddress>
|
||||
#include <QHostInfo>
|
||||
#include <QNetworkInterface>
|
||||
#include <QTime>
|
||||
|
||||
#include <QSctpSocket>
|
||||
#include <QSctpServer>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
|
||||
class tst_QSctpSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static void enterLoop(int secs)
|
||||
{
|
||||
++loopLevel;
|
||||
QTestEventLoop::instance().enterLoop(secs);
|
||||
--loopLevel;
|
||||
}
|
||||
static void exitLoop()
|
||||
{
|
||||
// Safe exit - if we aren't in an event loop, don't
|
||||
// exit one.
|
||||
if (loopLevel > 0)
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
static bool timeout()
|
||||
{
|
||||
return QTestEventLoop::instance().timeout();
|
||||
}
|
||||
|
||||
private slots:
|
||||
void constructing();
|
||||
void bind_data();
|
||||
void bind();
|
||||
void setInvalidSocketDescriptor();
|
||||
void setSocketDescriptor();
|
||||
void socketDescriptor();
|
||||
void hostNotFound();
|
||||
void connecting();
|
||||
void readAndWrite();
|
||||
void loop_data();
|
||||
void loop();
|
||||
void loopInTCPMode_data();
|
||||
void loopInTCPMode();
|
||||
void readDatagramAfterClose();
|
||||
void clientSendDataOnDelayedDisconnect();
|
||||
|
||||
protected slots:
|
||||
void exitLoopSlot();
|
||||
|
||||
private:
|
||||
static int loopLevel;
|
||||
};
|
||||
|
||||
int tst_QSctpSocket::loopLevel = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::constructing()
|
||||
{
|
||||
QSctpSocket socket;
|
||||
|
||||
// Check the initial state of the QSctpSocket.
|
||||
QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
|
||||
QVERIFY(socket.isSequential());
|
||||
QVERIFY(!socket.isOpen());
|
||||
QVERIFY(!socket.isValid());
|
||||
QCOMPARE(socket.socketType(), QAbstractSocket::SctpSocket);
|
||||
QCOMPARE(socket.maximumChannelCount(), 0);
|
||||
QCOMPARE(socket.readChannelCount(), 0);
|
||||
QCOMPARE(socket.writeChannelCount(), 0);
|
||||
|
||||
char c;
|
||||
QCOMPARE(socket.getChar(&c), false);
|
||||
QCOMPARE(socket.bytesAvailable(), Q_INT64_C(0));
|
||||
QCOMPARE(socket.canReadLine(), false);
|
||||
QCOMPARE(socket.readLine(), QByteArray());
|
||||
QCOMPARE(socket.socketDescriptor(), qintptr(-1));
|
||||
QCOMPARE(int(socket.localPort()), 0);
|
||||
QVERIFY(socket.localAddress() == QHostAddress());
|
||||
QCOMPARE(int(socket.peerPort()), 0);
|
||||
QVERIFY(socket.peerAddress() == QHostAddress());
|
||||
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
|
||||
QCOMPARE(socket.errorString(), QString("Unknown error"));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::bind_data()
|
||||
{
|
||||
QTest::addColumn<QString>("stringAddr");
|
||||
QTest::addColumn<bool>("successExpected");
|
||||
QTest::addColumn<QString>("stringExpectedLocalAddress");
|
||||
|
||||
// iterate all interfaces, add all addresses on them as test data
|
||||
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
|
||||
for (const QNetworkInterface &interface : interfaces) {
|
||||
if (!interface.isValid())
|
||||
continue;
|
||||
|
||||
for (const QNetworkAddressEntry &entry : interface.addressEntries()) {
|
||||
if (entry.ip().isInSubnet(QHostAddress::parseSubnet("fe80::/10"))
|
||||
|| entry.ip().isInSubnet(QHostAddress::parseSubnet("169.254/16")))
|
||||
continue; // link-local bind will fail, at least on Linux, so skip it.
|
||||
|
||||
QString ip(entry.ip().toString());
|
||||
QTest::newRow(ip.toLatin1().constData()) << ip << true << ip;
|
||||
}
|
||||
}
|
||||
|
||||
// additionally, try bind to known-bad addresses, and make sure this doesn't work
|
||||
// these ranges are guaranteed to be reserved for 'documentation purposes',
|
||||
// and thus, should be unused in the real world. Not that I'm assuming the
|
||||
// world is full of competent administrators, or anything.
|
||||
QStringList knownBad;
|
||||
knownBad << "198.51.100.1";
|
||||
knownBad << "2001:0DB8::1";
|
||||
foreach (const QString &badAddress, knownBad) {
|
||||
QTest::newRow(badAddress.toLatin1().constData()) << badAddress << false << QString();
|
||||
}
|
||||
}
|
||||
|
||||
// Testing bind function
|
||||
void tst_QSctpSocket::bind()
|
||||
{
|
||||
QFETCH(QString, stringAddr);
|
||||
QFETCH(bool, successExpected);
|
||||
QFETCH(QString, stringExpectedLocalAddress);
|
||||
|
||||
QHostAddress addr(stringAddr);
|
||||
QHostAddress expectedLocalAddress(stringExpectedLocalAddress);
|
||||
|
||||
QSctpSocket socket;
|
||||
qDebug() << "Binding " << addr;
|
||||
|
||||
if (successExpected)
|
||||
QVERIFY2(socket.bind(addr), qPrintable(socket.errorString()));
|
||||
else
|
||||
QVERIFY(!socket.bind(addr));
|
||||
|
||||
QCOMPARE(socket.localAddress(), expectedLocalAddress);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::setInvalidSocketDescriptor()
|
||||
{
|
||||
QSctpSocket socket;
|
||||
QCOMPARE(socket.socketDescriptor(), qintptr(INVALID_SOCKET));
|
||||
QVERIFY(!socket.setSocketDescriptor(-5, QAbstractSocket::UnconnectedState));
|
||||
QCOMPARE(socket.socketDescriptor(), qintptr(INVALID_SOCKET));
|
||||
|
||||
QCOMPARE(socket.error(), QAbstractSocket::UnsupportedSocketOperationError);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::setSocketDescriptor()
|
||||
{
|
||||
QSctpServer server;
|
||||
|
||||
server.setMaximumChannelCount(16);
|
||||
QVERIFY(server.listen());
|
||||
|
||||
SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
|
||||
|
||||
QVERIFY(sock != INVALID_SOCKET);
|
||||
QSctpSocket socket;
|
||||
QVERIFY(socket.setSocketDescriptor(sock, QAbstractSocket::UnconnectedState));
|
||||
QCOMPARE(socket.socketDescriptor(), qintptr(sock));
|
||||
QCOMPARE(socket.readChannelCount(), 0);
|
||||
QCOMPARE(socket.writeChannelCount(), 0);
|
||||
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(socket.waitForConnected(3000));
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
|
||||
QCOMPARE(socket.readChannelCount(), server.maximumChannelCount());
|
||||
QVERIFY(socket.writeChannelCount() <= server.maximumChannelCount());
|
||||
|
||||
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
|
||||
QVERIFY(acceptedSocket);
|
||||
QCOMPARE(acceptedSocket->readChannelCount(), socket.writeChannelCount());
|
||||
QCOMPARE(acceptedSocket->writeChannelCount(), socket.readChannelCount());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::socketDescriptor()
|
||||
{
|
||||
QSctpSocket socket;
|
||||
|
||||
QSctpServer server;
|
||||
|
||||
QVERIFY(server.listen());
|
||||
|
||||
QCOMPARE(socket.socketDescriptor(), qintptr(INVALID_SOCKET));
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
if (socket.state() != QAbstractSocket::ConnectedState) {
|
||||
QVERIFY((socket.state() == QAbstractSocket::HostLookupState
|
||||
&& socket.socketDescriptor() == INVALID_SOCKET)
|
||||
|| socket.state() == QAbstractSocket::ConnectingState);
|
||||
QVERIFY(socket.waitForConnected(3000));
|
||||
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
|
||||
}
|
||||
QVERIFY(socket.socketDescriptor() != INVALID_SOCKET);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::hostNotFound()
|
||||
{
|
||||
QSctpSocket socket;
|
||||
|
||||
socket.connectToHost("nosuchserver.qt-project.org", 80);
|
||||
QVERIFY(!socket.waitForConnected(3000));
|
||||
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
|
||||
QCOMPARE(socket.error(), QAbstractSocket::HostNotFoundError);
|
||||
}
|
||||
|
||||
// Testing connect function
|
||||
void tst_QSctpSocket::connecting()
|
||||
{
|
||||
QSctpServer server;
|
||||
|
||||
QVERIFY(server.listen());
|
||||
|
||||
QSctpSocket socket;
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(socket.waitForConnected(3000));
|
||||
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
|
||||
QVERIFY(acceptedSocket);
|
||||
|
||||
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(acceptedSocket->state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(socket.readChannelCount(), acceptedSocket->readChannelCount());
|
||||
QCOMPARE(socket.writeChannelCount(),acceptedSocket->writeChannelCount());
|
||||
}
|
||||
|
||||
// Testing read/write functions
|
||||
void tst_QSctpSocket::readAndWrite()
|
||||
{
|
||||
QSctpServer server;
|
||||
|
||||
QVERIFY(server.listen());
|
||||
|
||||
QSctpSocket socket;
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(socket.waitForConnected(3000));
|
||||
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
|
||||
QVERIFY(acceptedSocket);
|
||||
|
||||
QByteArray ba(1000, 1);
|
||||
QVERIFY(acceptedSocket->writeDatagram(ba));
|
||||
QVERIFY(acceptedSocket->waitForBytesWritten(3000));
|
||||
|
||||
QVERIFY(socket.waitForReadyRead(3000));
|
||||
QNetworkDatagram datagram = socket.readDatagram();
|
||||
QVERIFY(datagram.isValid());
|
||||
QCOMPARE(datagram.data(), ba);
|
||||
|
||||
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
|
||||
QCOMPARE(socket.errorString(), QString("Unknown error"));
|
||||
QCOMPARE(acceptedSocket->state(), QAbstractSocket::ConnectedState);
|
||||
QCOMPARE(acceptedSocket->error(), QAbstractSocket::UnknownSocketError);
|
||||
QCOMPARE(acceptedSocket->errorString(), QString("Unknown error"));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::loop_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("peterDatagram");
|
||||
QTest::addColumn<QByteArray>("paulDatagram");
|
||||
QTest::addColumn<int>("peterChannel");
|
||||
QTest::addColumn<int>("paulChannel");
|
||||
|
||||
QTest::newRow("\"Almond!\" | \"Joy!\"") << QByteArray("Almond!") << QByteArray("Joy!") << 0 << 0;
|
||||
QTest::newRow("\"A\" | \"B\"") << QByteArray("A") << QByteArray("B") << 1 << 1;
|
||||
QTest::newRow("\"AB\" | \"B\"") << QByteArray("AB") << QByteArray("B") << 0 << 1;
|
||||
QTest::newRow("\"AB\" | \"BB\"") << QByteArray("AB") << QByteArray("BB") << 1 << 0;
|
||||
QTest::newRow("\"A\\0B\" | \"B\\0B\"") << QByteArray::fromRawData("A\0B", 3) << QByteArray::fromRawData("B\0B", 3) << 0 << 1;
|
||||
QTest::newRow("BigDatagram") << QByteArray(600, '@') << QByteArray(600, '@') << 1 << 0;
|
||||
}
|
||||
|
||||
void tst_QSctpSocket::loop()
|
||||
{
|
||||
QFETCH(QByteArray, peterDatagram);
|
||||
QFETCH(QByteArray, paulDatagram);
|
||||
QFETCH(int, peterChannel);
|
||||
QFETCH(int, paulChannel);
|
||||
|
||||
QSctpServer server;
|
||||
|
||||
server.setMaximumChannelCount(10);
|
||||
QVERIFY(server.listen());
|
||||
|
||||
QSctpSocket peter;
|
||||
peter.setMaximumChannelCount(10);
|
||||
peter.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(peter.waitForConnected(3000));
|
||||
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
QSctpSocket *paul = server.nextPendingDatagramConnection();
|
||||
QVERIFY(paul);
|
||||
|
||||
peter.setCurrentWriteChannel(peterChannel);
|
||||
QVERIFY(peter.writeDatagram(peterDatagram));
|
||||
paul->setCurrentWriteChannel(paulChannel);
|
||||
QVERIFY(paul->writeDatagram(paulDatagram));
|
||||
QVERIFY(peter.flush());
|
||||
QVERIFY(paul->flush());
|
||||
|
||||
peter.setCurrentReadChannel(paulChannel);
|
||||
QVERIFY(peter.waitForReadyRead(3000));
|
||||
QCOMPARE(peter.bytesAvailable(), paulDatagram.size());
|
||||
QCOMPARE(peter.readDatagram().data(), paulDatagram);
|
||||
|
||||
paul->setCurrentReadChannel(peterChannel);
|
||||
QVERIFY(paul->waitForReadyRead(3000));
|
||||
QCOMPARE(paul->bytesAvailable(), peterDatagram.size());
|
||||
QCOMPARE(paul->readDatagram().data(), peterDatagram);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::loopInTCPMode_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("peterDatagram");
|
||||
QTest::addColumn<QByteArray>("paulDatagram");
|
||||
|
||||
QTest::newRow("\"Almond!\" | \"Joy!\"") << QByteArray("Almond!") << QByteArray("Joy!");
|
||||
QTest::newRow("\"A\" | \"B\"") << QByteArray("A") << QByteArray("B");
|
||||
QTest::newRow("\"AB\" | \"B\"") << QByteArray("AB") << QByteArray("B");
|
||||
QTest::newRow("\"AB\" | \"BB\"") << QByteArray("AB") << QByteArray("BB");
|
||||
QTest::newRow("\"A\\0B\" | \"B\\0B\"") << QByteArray::fromRawData("A\0B", 3) << QByteArray::fromRawData("B\0B", 3);
|
||||
QTest::newRow("BigDatagram") << QByteArray(600, '@') << QByteArray(600, '@');
|
||||
}
|
||||
|
||||
void tst_QSctpSocket::loopInTCPMode()
|
||||
{
|
||||
QFETCH(QByteArray, peterDatagram);
|
||||
QFETCH(QByteArray, paulDatagram);
|
||||
|
||||
QSctpServer server;
|
||||
|
||||
server.setMaximumChannelCount(-1);
|
||||
QVERIFY(server.listen());
|
||||
|
||||
QSctpSocket peter;
|
||||
peter.setMaximumChannelCount(-1);
|
||||
peter.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(peter.waitForConnected(3000));
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
|
||||
QTcpSocket *paul = server.nextPendingConnection();
|
||||
QVERIFY(paul);
|
||||
|
||||
QCOMPARE(peter.write(peterDatagram), qint64(peterDatagram.size()));
|
||||
QCOMPARE(paul->write(paulDatagram), qint64(paulDatagram.size()));
|
||||
QVERIFY(peter.flush());
|
||||
QVERIFY(paul->flush());
|
||||
|
||||
QVERIFY(peter.waitForReadyRead(3000));
|
||||
QVERIFY(paul->waitForReadyRead(3000));
|
||||
|
||||
QCOMPARE(peter.bytesAvailable(), paulDatagram.size());
|
||||
QByteArray peterBuffer = peter.readAll();
|
||||
|
||||
QCOMPARE(paul->bytesAvailable(), peterDatagram.size());
|
||||
QByteArray paulBuffer = paul->readAll();
|
||||
|
||||
QCOMPARE(peterBuffer, paulDatagram);
|
||||
QCOMPARE(paulBuffer, peterDatagram);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::exitLoopSlot()
|
||||
{
|
||||
exitLoop();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void tst_QSctpSocket::readDatagramAfterClose()
|
||||
{
|
||||
QSctpServer server;
|
||||
|
||||
QVERIFY(server.listen());
|
||||
|
||||
QSctpSocket socket;
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(socket.waitForConnected(3000));
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
|
||||
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
|
||||
QVERIFY(acceptedSocket);
|
||||
|
||||
connect(&socket, &QIODevice::readyRead, this, &tst_QSctpSocket::exitLoopSlot);
|
||||
|
||||
QByteArray ba(1000, 1);
|
||||
QVERIFY(acceptedSocket->writeDatagram(ba));
|
||||
|
||||
enterLoop(10);
|
||||
if (timeout())
|
||||
QFAIL("Network operation timed out");
|
||||
|
||||
QCOMPARE(socket.bytesAvailable(), ba.size());
|
||||
socket.close();
|
||||
QVERIFY(!socket.readDatagram().isValid());
|
||||
}
|
||||
|
||||
// Test buffered socket properly send data on delayed disconnect
|
||||
void tst_QSctpSocket::clientSendDataOnDelayedDisconnect()
|
||||
{
|
||||
QSctpServer server;
|
||||
|
||||
QVERIFY(server.listen());
|
||||
|
||||
// Connect to server, write data and close socket
|
||||
QSctpSocket socket;
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(socket.waitForConnected(3000));
|
||||
|
||||
QByteArray sendData("GET /\r\n");
|
||||
sendData = sendData.repeated(1000);
|
||||
QVERIFY(socket.writeDatagram(sendData));
|
||||
socket.close();
|
||||
QCOMPARE(socket.state(), QAbstractSocket::ClosingState);
|
||||
QVERIFY(socket.waitForDisconnected(3000));
|
||||
|
||||
QVERIFY(server.waitForNewConnection(3000));
|
||||
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
|
||||
QVERIFY(acceptedSocket);
|
||||
|
||||
QVERIFY(acceptedSocket->waitForReadyRead(3000));
|
||||
QNetworkDatagram datagram = acceptedSocket->readDatagram();
|
||||
QVERIFY(datagram.isValid());
|
||||
QCOMPARE(datagram.data(), sendData);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSctpSocket)
|
||||
|
||||
#include "tst_qsctpsocket.moc"
|
13
tests/auto/network/socket/qsocks5socketengine/BLACKLIST
Normal file
13
tests/auto/network/socket/qsocks5socketengine/BLACKLIST
Normal file
@ -0,0 +1,13 @@
|
||||
[udpTest]
|
||||
*
|
||||
[passwordAuth]
|
||||
ubuntu
|
||||
# QTBUG-101274
|
||||
qnx ci
|
||||
# QTBUG-74162
|
||||
[passwordAuth2]
|
||||
ubuntu
|
||||
[downloadBigFile]
|
||||
windows-10 msvc-2015
|
||||
windows-7sp1
|
||||
|
29
tests/auto/network/socket/qsocks5socketengine/CMakeLists.txt
Normal file
29
tests/auto/network/socket/qsocks5socketengine/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
## tst_qsocks5socketengine Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qsocks5socketengine
|
||||
SOURCES
|
||||
tst_qsocks5socketengine.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::NetworkPrivate
|
||||
QT_TEST_SERVER_LIST "danted" "apache2" "cyrus"
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
# QT_TEST_SERVER_LIST = "danted" "apache2" "cyrus"
|
||||
|
||||
qt_internal_extend_target(tst_qsocks5socketengine CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
File diff suppressed because it is too large
Load Diff
17
tests/auto/network/socket/qtcpserver/BLACKLIST
Normal file
17
tests/auto/network/socket/qtcpserver/BLACKLIST
Normal file
@ -0,0 +1,17 @@
|
||||
[listenWhileListening:WithSocks5Proxy]
|
||||
linux
|
||||
windows
|
||||
[ipv6Server]
|
||||
windows-7sp1
|
||||
windows-10 msvc-2017
|
||||
[ipv6Server:WithoutProxy]
|
||||
windows
|
||||
osx
|
||||
[serverAddress]
|
||||
# QTBUG-103056
|
||||
qnx
|
||||
windows-7sp1
|
||||
windows-10
|
||||
|
||||
[linkLocal]
|
||||
macos arm
|
5
tests/auto/network/socket/qtcpserver/CMakeLists.txt
Normal file
5
tests/auto/network/socket/qtcpserver/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_subdirectory(crashingServer)
|
||||
add_subdirectory(test)
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## crashingServer Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_executable(crashingServer
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
58
tests/auto/network/socket/qtcpserver/crashingServer/main.cpp
Normal file
58
tests/auto/network/socket/qtcpserver/crashingServer/main.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
// 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>
|
||||
#include <QtNetwork>
|
||||
#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
|
||||
# include <crtdbg.h>
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
# include <sys/resource.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
|
||||
// Windows: Suppress crash notification dialog.
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
|
||||
#elif defined(RLIMIT_CORE)
|
||||
// Unix: set our core dump limit to zero to request no dialogs.
|
||||
if (struct rlimit rlim; getrlimit(RLIMIT_CORE, &rlim) == 0) {
|
||||
rlim.rlim_cur = 0;
|
||||
setrlimit(RLIMIT_CORE, &rlim);
|
||||
}
|
||||
#endif
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "Need a port number\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int port = QByteArrayView(argv[1]).toInt();
|
||||
QTcpServer server;
|
||||
if (!server.listen(QHostAddress::LocalHost, port)) {
|
||||
fprintf(stderr, "Failed to listen: %s\n", server.errorString().toLatin1().constData());
|
||||
if (server.serverError() == QTcpSocket::AddressInUseError) {
|
||||
// let's see if we can find the process that would be holding this
|
||||
// still open
|
||||
#ifdef Q_OS_LINUX
|
||||
static const char *ss_args[] = {
|
||||
"ss", "-nap", "sport", "=", argv[1], nullptr
|
||||
};
|
||||
dup2(STDERR_FILENO, STDOUT_FILENO);
|
||||
execvp(ss_args[0], const_cast<char **>(ss_args));
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Listening\n");
|
||||
fflush(stdout);
|
||||
|
||||
server.waitForNewConnection(5000);
|
||||
qFatal("Crash");
|
||||
return 0;
|
||||
}
|
27
tests/auto/network/socket/qtcpserver/test/CMakeLists.txt
Normal file
27
tests/auto/network/socket/qtcpserver/test/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtcpserver Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtcpserver
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
|
||||
SOURCES
|
||||
../tst_qtcpserver.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
QT_TEST_SERVER_LIST "danted" "cyrus" "squid" "ftp-proxy"
|
||||
)
|
||||
|
||||
add_dependencies(tst_qtcpserver
|
||||
crashingServer
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qtcpserver CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
1151
tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
Normal file
1151
tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
77
tests/auto/network/socket/qtcpsocket/BLACKLIST
Normal file
77
tests/auto/network/socket/qtcpsocket/BLACKLIST
Normal file
@ -0,0 +1,77 @@
|
||||
[timeoutConnect:ip]
|
||||
windows
|
||||
# QTBUG-101274
|
||||
[timeoutConnect:WithSocks5Proxy:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithSocks5ProxyAuth:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithHttpProxy:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithHttpProxyBasicAuth:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithSocks5Proxy SSL:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithSocks5AuthProxy SSL:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithHttpProxy SSL:ip]
|
||||
qnx ci
|
||||
[timeoutConnect:WithHttpProxyBasicAuth SSL:ip]
|
||||
qnx ci
|
||||
[suddenRemoteDisconnect:WithoutProxy:Qt4 Client <-> Qt4 Server]
|
||||
qnx ci
|
||||
# QTBUG-66247
|
||||
[delayedClose:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[delayedClose:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[partialRead:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[partialRead:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[unget:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[unget:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[readAllAfterClose:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[readAllAfterClose:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[openCloseOpenClose:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[openCloseOpenClose:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[connectDisconnectConnectDisconnect:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[connectDisconnectConnectDisconnect:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[downloadBigFile:WithSocks5Proxy]
|
||||
windows-10 gcc developer-build
|
||||
[downloadBigFile:WithSocks5Proxy SSL]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithoutProxy:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithSocks5Proxy:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithSocks5ProxyAuth:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithHttpProxy:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithHttpProxyBasicAuth:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithoutProxy SSL:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithSocks5Proxy SSL:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithSocks5AuthProxy SSL:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithHttpProxy SSL:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[connectToHostError:WithHttpProxyBasicAuth SSL:localhost no service]
|
||||
windows-10 gcc developer-build
|
||||
[bind]
|
||||
macos arm
|
||||
# QTBUG-101274
|
||||
[bindThenResolveHost:WithoutProxy:first-fail]
|
||||
qnx ci
|
||||
[bindThenResolveHost:WithoutProxy SSL:first-fail]
|
||||
qnx ci
|
10
tests/auto/network/socket/qtcpsocket/CMakeLists.txt
Normal file
10
tests/auto/network/socket/qtcpsocket/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
add_subdirectory(test)
|
||||
if(NOT VXWORKS)
|
||||
add_subdirectory(stressTest)
|
||||
endif()
|
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## stressTest Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_executable(stressTest
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
SOURCES
|
||||
Test.cpp Test.h
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
Qt::Test
|
||||
)
|
109
tests/auto/network/socket/qtcpsocket/stressTest/Test.cpp
Normal file
109
tests/auto/network/socket/qtcpsocket/stressTest/Test.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// Qt
|
||||
#include <QByteArray>
|
||||
#include <QCoreApplication>
|
||||
#include <QDataStream>
|
||||
#include <QTimer>
|
||||
|
||||
// Test
|
||||
#include "Test.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
My4Socket::My4Socket(QObject *parent)
|
||||
: QTcpSocket(parent), safeShutDown(false)
|
||||
{
|
||||
connect(this, SIGNAL(readyRead()), this, SLOT(read()));
|
||||
connect(this, SIGNAL(disconnected()), this, SLOT(closed()));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void My4Socket::read(void)
|
||||
{
|
||||
QDataStream in(this);
|
||||
|
||||
quint32 num = 0;
|
||||
quint32 reply = 0;
|
||||
|
||||
while (bytesAvailable()) {
|
||||
in >> num;
|
||||
if (num == 42) {
|
||||
safeShutDown = true;
|
||||
qDebug("SUCCESS");
|
||||
QCoreApplication::instance()->quit();
|
||||
return;
|
||||
}
|
||||
reply = num + 1;
|
||||
if (reply == 42)
|
||||
++reply;
|
||||
}
|
||||
|
||||
// Reply with a bigger number
|
||||
sendTest(reply);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void My4Socket::closed(void)
|
||||
{
|
||||
if (!safeShutDown)
|
||||
qDebug("FAILED");
|
||||
QCoreApplication::instance()->quit();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void My4Socket::sendTest(quint32 num)
|
||||
{
|
||||
QByteArray block;
|
||||
QDataStream out(&block, QIODevice::WriteOnly);
|
||||
out << num;
|
||||
|
||||
write(block, block.size());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
My4Server::My4Server(QObject *parent)
|
||||
: QTcpServer(parent)
|
||||
{
|
||||
if (listen(QHostAddress::Any, 7700))
|
||||
qDebug("qt4server");
|
||||
QTimer::singleShot(5000, this, SLOT(stopServer()));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void My4Server::incomingConnection(qintptr socketId)
|
||||
{
|
||||
m_socket = new My4Socket(this);
|
||||
m_socket->setSocketDescriptor(socketId);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void My4Server::stopServer()
|
||||
{
|
||||
if (m_socket) {
|
||||
qDebug("SUCCESS");
|
||||
m_socket->safeShutDown = true;
|
||||
m_socket->sendTest(42);
|
||||
} else {
|
||||
QCoreApplication::instance()->quit();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Test::Test(Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case Qt4Client: {
|
||||
qDebug("qt4client");
|
||||
My4Socket *s = new My4Socket(this);
|
||||
s->connectToHost("localhost", 7700);
|
||||
s->sendTest(1);
|
||||
break;
|
||||
}
|
||||
case Qt4Server: {
|
||||
new My4Server(this);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
57
tests/auto/network/socket/qtcpsocket/stressTest/Test.h
Normal file
57
tests/auto/network/socket/qtcpsocket/stressTest/Test.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#ifndef TEST_H
|
||||
#define TEST_H
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class My4Socket : public QTcpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
My4Socket(QObject *parent);
|
||||
|
||||
void sendTest(quint32 num);
|
||||
bool safeShutDown;
|
||||
|
||||
private slots:
|
||||
void read();
|
||||
void closed();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class My4Server : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
My4Server(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void incomingConnection(qintptr socket) override;
|
||||
|
||||
private slots:
|
||||
void stopServer();
|
||||
|
||||
private:
|
||||
My4Socket *m_socket;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class Test : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
Qt4Client,
|
||||
Qt4Server,
|
||||
};
|
||||
Test(Type type);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#endif // TEST_H
|
29
tests/auto/network/socket/qtcpsocket/stressTest/main.cpp
Normal file
29
tests/auto/network/socket/qtcpsocket/stressTest/main.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 "Test.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
QString arg;
|
||||
if (app.arguments().size() > 1)
|
||||
arg = app.arguments().at(1).toLower().trimmed();
|
||||
|
||||
Test::Type type;
|
||||
if (arg == QLatin1String("qt4client"))
|
||||
type = Test::Qt4Client;
|
||||
else if (arg == QLatin1String("qt4server"))
|
||||
type = Test::Qt4Server;
|
||||
else {
|
||||
qDebug("usage: ./stressTest <qt4client|qt4server>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Test test(type);
|
||||
|
||||
return app.exec();
|
||||
}
|
24
tests/auto/network/socket/qtcpsocket/test/CMakeLists.txt
Normal file
24
tests/auto/network/socket/qtcpsocket/test/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtcpsocket Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtcpsocket
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
|
||||
SOURCES
|
||||
../tst_qtcpsocket.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::NetworkPrivate
|
||||
QT_TEST_SERVER_LIST "danted" "squid" "apache2" "ftp-proxy" "vsftpd" "iptables" "cyrus"
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qtcpsocket CONDITION WIN32
|
||||
LIBRARIES
|
||||
ws2_32
|
||||
)
|
3220
tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
Normal file
3220
tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
Normal file
File diff suppressed because it is too large
Load Diff
13
tests/auto/network/socket/qudpsocket/BLACKLIST
Normal file
13
tests/auto/network/socket/qudpsocket/BLACKLIST
Normal file
@ -0,0 +1,13 @@
|
||||
[writeDatagramToNonExistingPeer]
|
||||
windows
|
||||
# QTBUG-85364
|
||||
windows-10 gcc cmake
|
||||
[readyReadForEmptyDatagram]
|
||||
opensuse-leap
|
||||
[echo]
|
||||
opensuse-42.3
|
||||
[multicast]
|
||||
centos
|
||||
macos arm
|
||||
[linkLocalIPv6]
|
||||
macos arm
|
5
tests/auto/network/socket/qudpsocket/CMakeLists.txt
Normal file
5
tests/auto/network/socket/qudpsocket/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(clientserver)
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## clientserver Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_executable(clientserver
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
136
tests/auto/network/socket/qudpsocket/clientserver/main.cpp
Normal file
136
tests/auto/network/socket/qudpsocket/clientserver/main.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
// 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 <QtNetwork>
|
||||
|
||||
class ClientServer : public QUdpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Type {
|
||||
ConnectedClient,
|
||||
UnconnectedClient,
|
||||
Server
|
||||
};
|
||||
|
||||
ClientServer(Type type, const QString &host, quint16 port)
|
||||
: type(type)
|
||||
{
|
||||
switch (type) {
|
||||
case Server:
|
||||
if (bind(0, ShareAddress | ReuseAddressHint)) {
|
||||
printf("%d\n", localPort());
|
||||
} else {
|
||||
printf("XXX\n");
|
||||
}
|
||||
break;
|
||||
case ConnectedClient:
|
||||
connectToHost(host, port);
|
||||
startTimer(250);
|
||||
printf("ok\n");
|
||||
break;
|
||||
case UnconnectedClient:
|
||||
peerAddress = QHostAddress(host);
|
||||
peerPort = port;
|
||||
if (bind(QHostAddress::Any, port + 1, ShareAddress | ReuseAddressHint)) {
|
||||
startTimer(250);
|
||||
printf("ok\n");
|
||||
} else {
|
||||
printf("XXX\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
connect(this, SIGNAL(readyRead()), this, SLOT(readTestData()));
|
||||
}
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override
|
||||
{
|
||||
static int n = 0;
|
||||
switch (type) {
|
||||
case ConnectedClient:
|
||||
write(QByteArray::number(n++));
|
||||
break;
|
||||
case UnconnectedClient:
|
||||
writeDatagram(QByteArray::number(n++), peerAddress, peerPort);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QUdpSocket::timerEvent(event);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void readTestData()
|
||||
{
|
||||
printf("readData()\n");
|
||||
switch (type) {
|
||||
case ConnectedClient: {
|
||||
while (bytesAvailable() || hasPendingDatagrams()) {
|
||||
QByteArray data = readAll();
|
||||
printf("got %d\n", data.toInt());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UnconnectedClient: {
|
||||
while (hasPendingDatagrams()) {
|
||||
QByteArray data;
|
||||
data.resize(pendingDatagramSize());
|
||||
readDatagram(data.data(), data.size());
|
||||
printf("got %d\n", data.toInt());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Server: {
|
||||
while (hasPendingDatagrams()) {
|
||||
QHostAddress sender;
|
||||
quint16 senderPort;
|
||||
QByteArray data;
|
||||
data.resize(pendingDatagramSize());
|
||||
readDatagram(data.data(), data.size(), &sender, &senderPort);
|
||||
printf("got %d\n", data.toInt());
|
||||
printf("sending %d\n", data.toInt() * 2);
|
||||
writeDatagram(QByteArray::number(data.toInt() * 2), sender, senderPort);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
private:
|
||||
Type type;
|
||||
QHostAddress peerAddress;
|
||||
quint16 peerPort;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
ClientServer::Type type;
|
||||
if (app.arguments().size() < 4) {
|
||||
qDebug("usage: %s [ConnectedClient <server> <port>|UnconnectedClient <server> <port>|Server]", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
QString arg = app.arguments().at(1).trimmed().toLower();
|
||||
if (arg == "connectedclient") {
|
||||
type = ClientServer::ConnectedClient;
|
||||
} else if (arg == "unconnectedclient") {
|
||||
type = ClientServer::UnconnectedClient;
|
||||
} else if (arg == "server") {
|
||||
type = ClientServer::Server;
|
||||
} else {
|
||||
qDebug("usage: %s [ConnectedClient <server> <port>|UnconnectedClient <server> <port>|Server]", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ClientServer clientServer(type, app.arguments().at(2),
|
||||
app.arguments().at(3).toInt());
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
16
tests/auto/network/socket/qudpsocket/test/CMakeLists.txt
Normal file
16
tests/auto/network/socket/qudpsocket/test/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qudpsocket Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qudpsocket
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
|
||||
SOURCES
|
||||
../tst_qudpsocket.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
Qt::TestPrivate
|
||||
QT_TEST_SERVER_LIST "danted" "echo"
|
||||
)
|
1912
tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
Normal file
1912
tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## udpServer Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_executable(udpServer
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/./"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
)
|
66
tests/auto/network/socket/qudpsocket/udpServer/main.cpp
Normal file
66
tests/auto/network/socket/qudpsocket/udpServer/main.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
// 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 <QtNetwork>
|
||||
|
||||
class Server : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); }
|
||||
|
||||
bool bind(quint16 port)
|
||||
{
|
||||
const bool result = serverSocket.bind(QHostAddress::Any, port,
|
||||
QUdpSocket::ReuseAddressHint
|
||||
| QUdpSocket::ShareAddress);
|
||||
if (result) {
|
||||
printf("OK\n");
|
||||
} else {
|
||||
printf("FAILED: %s\n", qPrintable(serverSocket.errorString()));
|
||||
}
|
||||
fflush(stdout);
|
||||
return result;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void sendEcho()
|
||||
{
|
||||
QHostAddress senderAddress;
|
||||
quint16 senderPort;
|
||||
|
||||
char data[1024];
|
||||
qint64 bytes = serverSocket.readDatagram(data, sizeof(data), &senderAddress, &senderPort);
|
||||
if (bytes == 1 && data[0] == '\0')
|
||||
QCoreApplication::instance()->quit();
|
||||
|
||||
for (int i = 0; i < bytes; ++i)
|
||||
data[i] += 1;
|
||||
serverSocket.writeDatagram(data, bytes, senderAddress, senderPort);
|
||||
}
|
||||
|
||||
private:
|
||||
QUdpSocket serverSocket;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QStringList arguments = QCoreApplication::arguments();
|
||||
arguments.pop_front();
|
||||
quint16 port = 0;
|
||||
if (!arguments.isEmpty())
|
||||
port = arguments.constFirst().toUShort();
|
||||
if (!port) {
|
||||
printf("Specify port number\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Server server;
|
||||
if (!server.bind(port))
|
||||
return -2;
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
Reference in New Issue
Block a user