summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/io')
-rw-r--r--tests/auto/corelib/io/io.pro9
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp7
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp41
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp1
-rw-r--r--tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp2
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/main.cpp85
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp68
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp4
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp17
-rw-r--r--tests/auto/corelib/io/qwinoverlappedionotifier/qwinoverlappedionotifier.pro4
-rw-r--r--tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp331
11 files changed, 181 insertions, 388 deletions
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
index 01ed84fda9..bd2a9f4c8e 100644
--- a/tests/auto/corelib/io/io.pro
+++ b/tests/auto/corelib/io/io.pro
@@ -34,12 +34,6 @@ SUBDIRS=\
qurl \
qurlinternal \
qurlquery \
- qwinoverlappedionotifier \
-
-!win32 {
- SUBDIRS -=\
- qwinoverlappedionotifier
-}
!qtHaveModule(gui): SUBDIRS -= \
qdatastream \
@@ -73,5 +67,4 @@ win32:!qtConfig(private_tests): SUBDIRS -= \
qprocess-noapplication
winrt: SUBDIRS -= \
- qstorageinfo \
- qwinoverlappedionotifier
+ qstorageinfo
diff --git a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
index dba920d1f7..4e5059c1a2 100644
--- a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
+++ b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
@@ -353,6 +353,13 @@ public:
return QDateTime();
}
+ bool setFileTime(const QDateTime &newDate, FileTime time)
+ {
+ Q_UNUSED(newDate);
+ Q_UNUSED(time);
+ return false;
+ }
+
void setFileName(const QString &file)
{
if (openForRead_ || openForWrite_)
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index 7147405f3b..b43ea7cfa5 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -51,6 +51,7 @@ private slots:
void qDebugQChar() const;
void qDebugQString() const;
void qDebugQStringRef() const;
+ void qDebugQStringView() const;
void qDebugQLatin1String() const;
void qDebugQByteArray() const;
void qDebugQFlags() const;
@@ -492,6 +493,46 @@ void tst_QDebug::qDebugQStringRef() const
}
}
+void tst_QDebug::qDebugQStringView() const
+{
+ /* Use a basic string. */
+ {
+ QLatin1String file, function;
+ int line = 0;
+ const QStringView inView = QStringViewLiteral("input");
+
+ MessageHandlerSetter mhs(myMessageHandler);
+ { qDebug() << inView; }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = QLatin1String(__FILE__); line = __LINE__ - 2; function = QLatin1String(Q_FUNC_INFO);
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QLatin1String("\"input\""));
+ QCOMPARE(QLatin1String(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QLatin1String(s_function), function);
+ }
+
+ /* Use a null QStringView. */
+ {
+ QString file, function;
+ int line = 0;
+
+ const QStringView inView;
+
+ MessageHandlerSetter mhs(myMessageHandler);
+ { qDebug() << inView; }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QLatin1String("\"\""));
+ QCOMPARE(QLatin1String(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QLatin1String(s_function), function);
+ }
+}
+
void tst_QDebug::qDebugQLatin1String() const
{
QString file, function;
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 9751bb4c9e..f97501e8a6 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -2077,6 +2077,7 @@ public:
uint ownerId(FileOwner) const { return 0; }
QString owner(FileOwner) const { return QString(); }
QDateTime fileTime(FileTime) const { return QDateTime(); }
+ bool setFileTime(const QDateTime &newDate, FileTime time) { return false; }
private:
int number;
diff --git a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
index b0acb1c58d..b78fa29fb6 100644
--- a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
+++ b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
@@ -64,7 +64,7 @@ void tst_QNoDebug::noDebugOutput() const
void tst_QNoDebug::streaming() const
{
QDateTime dt(QDate(1,2,3),QTime(4,5,6));
- const QByteArray debugString = dt.toString(QStringLiteral("yyyy-MM-dd HH:mm:ss.zzz t")).toLatin1();
+ const QByteArray debugString = dt.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t")).toLatin1();
const QByteArray message = "QDateTime(" + debugString + " Qt::TimeSpec(LocalTime))";
QTest::ignoreMessage(QtWarningMsg, message.constData());
qWarning() << dt;
diff --git a/tests/auto/corelib/io/qprocess/testDetached/main.cpp b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
index 702cabe873..c10e32d584 100644
--- a/tests/auto/corelib/io/qprocess/testDetached/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
@@ -40,32 +40,89 @@
#include <windows.h>
#endif
+static void writeStuff(QFile &f)
+{
+ f.write(QDir::currentPath().toUtf8());
+ f.putChar('\n');
+#if defined(Q_OS_UNIX)
+ f.write(QByteArray::number(quint64(getpid())));
+#elif defined(Q_OS_WIN)
+ f.write(QByteArray::number(quint64(GetCurrentProcessId())));
+#endif
+ f.putChar('\n');
+ f.write(qgetenv("tst_QProcess"));
+ f.putChar('\n');
+}
+
+struct Args
+{
+ int exitCode = 0;
+ QByteArray errorMessage;
+ QString fileName;
+ FILE *channel = nullptr;
+ QByteArray channelName;
+};
+
+static Args parseArguments(const QStringList &args)
+{
+ Args result;
+ if (args.count() < 2) {
+ result.exitCode = 128;
+ result.errorMessage = "Usage: testDetached [--out-channel={stdout|stderr}] filename.txt\n";
+ return result;
+ }
+ for (const QString &arg : args) {
+ if (arg.startsWith("--")) {
+ if (!arg.startsWith("--out-channel=")) {
+ result.exitCode = 2;
+ result.errorMessage = "Unknown argument " + arg.toLocal8Bit();
+ return result;
+ }
+ result.channelName = arg.mid(14).toLocal8Bit();
+ if (result.channelName == "stdout") {
+ result.channel = stdout;
+ } else if (result.channelName == "stderr") {
+ result.channel = stderr;
+ } else {
+ result.exitCode = 3;
+ result.errorMessage = "Unknown channel " + result.channelName;
+ return result;
+ }
+ } else {
+ result.fileName = arg;
+ }
+ }
+ return result;
+}
+
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
- QStringList args = app.arguments();
- if (args.count() != 2) {
- fprintf(stderr, "Usage: testDetached filename.txt\n");
- return 128;
+ const Args args = parseArguments(app.arguments());
+ if (args.exitCode) {
+ fprintf(stderr, "testDetached: %s\n", args.errorMessage.constData());
+ return args.exitCode;
}
- QFile f(args.at(1));
+ if (args.channel) {
+ QFile channel;
+ if (!channel.open(args.channel, QIODevice::WriteOnly | QIODevice::Text)) {
+ fprintf(stderr, "Cannot open channel %s for writing: %s\n",
+ qPrintable(args.channelName), qPrintable(channel.errorString()));
+ return 4;
+ }
+ writeStuff(channel);
+ }
+
+ QFile f(args.fileName);
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
fprintf(stderr, "Cannot open %s for writing: %s\n",
qPrintable(f.fileName()), qPrintable(f.errorString()));
return 1;
}
- f.write(QDir::currentPath().toUtf8());
- f.putChar('\n');
-#if defined(Q_OS_UNIX)
- f.write(QByteArray::number(quint64(getpid())));
-#elif defined(Q_OS_WIN)
- f.write(QByteArray::number(quint64(GetCurrentProcessId())));
-#endif
- f.putChar('\n');
-
+ writeStuff(f);
f.close();
return 0;
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index f4d6d5cb40..de6eb28503 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -127,7 +127,8 @@ private slots:
void systemEnvironment();
void lockupsInStartDetached();
void waitForReadyReadForNonexistantProcess();
- void detachedWorkingDirectoryAndPid();
+ void detachedProcessParameters_data();
+ void detachedProcessParameters();
void startFinishStartFinish();
void invalidProgramString_data();
void invalidProgramString();
@@ -2072,21 +2073,54 @@ void tst_QProcess::fileWriterProcess()
} while (stopWatch.elapsed() < 3000);
}
-void tst_QProcess::detachedWorkingDirectoryAndPid()
+void tst_QProcess::detachedProcessParameters_data()
{
+ QTest::addColumn<QString>("outChannel");
+ QTest::newRow("none") << QString();
+ QTest::newRow("stdout") << QString("stdout");
+ QTest::newRow("stderr") << QString("stderr");
+}
+
+void tst_QProcess::detachedProcessParameters()
+{
+ QFETCH(QString, outChannel);
qint64 pid;
QFile infoFile(m_temporaryDir.path() + QLatin1String("/detachedinfo.txt"));
if (infoFile.exists())
QVERIFY(infoFile.remove());
+ QFile channelFile(m_temporaryDir.path() + QLatin1String("detachedinfo2.txt"));
+ if (channelFile.exists())
+ QVERIFY(channelFile.remove());
QString workingDir = QDir::currentPath() + "/testDetached";
QVERIFY(QFile::exists(workingDir));
- QStringList args;
- args << infoFile.fileName();
- QVERIFY(QProcess::startDetached(QDir::currentPath() + QLatin1String("/testDetached/testDetached"), args, workingDir, &pid));
+ QVERIFY(qgetenv("tst_QProcess").isEmpty());
+ QByteArray envVarValue("foobarbaz");
+ QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
+ environment.insert(QStringLiteral("tst_QProcess"), QString::fromUtf8(envVarValue));
+
+ QProcess process;
+ process.setProgram(QDir::currentPath() + QLatin1String("/testDetached/testDetached"));
+#ifdef Q_OS_WIN
+ int modifierCalls = 0;
+ process.setCreateProcessArgumentsModifier(
+ [&modifierCalls] (QProcess::CreateProcessArguments *) { modifierCalls++; });
+#endif
+ QStringList args(infoFile.fileName());
+ if (!outChannel.isEmpty()) {
+ args << QStringLiteral("--out-channel=") + outChannel;
+ if (outChannel == "stdout")
+ process.setStandardOutputFile(channelFile.fileName());
+ else if (outChannel == "stderr")
+ process.setStandardErrorFile(channelFile.fileName());
+ }
+ process.setArguments(args);
+ process.setWorkingDirectory(workingDir);
+ process.setProcessEnvironment(environment);
+ QVERIFY(process.startDetached(&pid));
QFileInfo fi(infoFile);
fi.setCaching(false);
@@ -2097,19 +2131,35 @@ void tst_QProcess::detachedWorkingDirectoryAndPid()
}
QVERIFY(infoFile.open(QIODevice::ReadOnly | QIODevice::Text));
- QString actualWorkingDir = QString::fromUtf8(infoFile.readLine());
- actualWorkingDir.chop(1); // strip off newline
- QByteArray processIdString = infoFile.readLine();
- processIdString.chop(1);
+ QString actualWorkingDir = QString::fromUtf8(infoFile.readLine()).trimmed();
+ QByteArray processIdString = infoFile.readLine().trimmed();
+ QByteArray actualEnvVarValue = infoFile.readLine().trimmed();
+ QByteArray infoFileContent;
+ if (!outChannel.isEmpty()) {
+ infoFile.seek(0);
+ infoFileContent = infoFile.readAll();
+ }
infoFile.close();
infoFile.remove();
+ if (!outChannel.isEmpty()) {
+ QVERIFY(channelFile.open(QIODevice::ReadOnly | QIODevice::Text));
+ QByteArray channelContent = channelFile.readAll();
+ channelFile.close();
+ channelFile.remove();
+ QCOMPARE(channelContent, infoFileContent);
+ }
+
bool ok = false;
qint64 actualPid = processIdString.toLongLong(&ok);
QVERIFY(ok);
QCOMPARE(actualWorkingDir, workingDir);
QCOMPARE(actualPid, pid);
+ QCOMPARE(actualEnvVarValue, envVarValue);
+#ifdef Q_OS_WIN
+ QCOMPARE(modifierCalls, 1);
+#endif
}
void tst_QProcess::switchReadChannels()
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index 59cd3a8411..17bcde4992 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -866,8 +866,6 @@ void tst_QTemporaryFile::guaranteeUnique()
// First pass. See which filename QTemporaryFile will try first.
{
- // Fix the random seed.
- qsrand(1135);
QTemporaryFile tmpFile("testFile1.XXXXXX");
tmpFile.open();
takenFileName = tmpFile.fileName();
@@ -881,8 +879,6 @@ void tst_QTemporaryFile::guaranteeUnique()
// Second pass, now we have blocked its first attempt with a directory.
{
- // Fix the random seed.
- qsrand(1135);
QTemporaryFile tmpFile("testFile1.XXXXXX");
QVERIFY(tmpFile.open());
QString uniqueFileName = tmpFile.fileName();
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index ebc240c285..1cbb7ad19c 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -1384,18 +1384,6 @@ void tst_QUrl::compat_constructor_01_data()
void tst_QUrl::compat_constructor_01()
{
- /* The following should work as expected:
- *
- * QUrlOperator op;
- * op.copy( QString( "Makefile" ),
- * QString("ftp://rms:grmpf12@nibbler/home/rms/tmp"),
- * false );
- *
- * as well as the following:
- *
- * QUrlOperator op;
- * op.copy(QString("ftp://ftp.qt-project.org/qt/INSTALL"), ".");
- */
QFETCH( QString, urlStr );
{
@@ -1425,11 +1413,6 @@ void tst_QUrl::compat_constructor_02_data()
void tst_QUrl::compat_constructor_02()
{
- /* The following should work as expected:
- *
- * QUrlOperator op( "ftp://ftp.qt-project.org/qt" );
- * op.copy(QString("INSTALL"), ".");
- */
QFETCH( QString, urlStr );
QFETCH( QString, fileName );
diff --git a/tests/auto/corelib/io/qwinoverlappedionotifier/qwinoverlappedionotifier.pro b/tests/auto/corelib/io/qwinoverlappedionotifier/qwinoverlappedionotifier.pro
deleted file mode 100644
index 4f0e9da3c2..0000000000
--- a/tests/auto/corelib/io/qwinoverlappedionotifier/qwinoverlappedionotifier.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qwinoverlappedionotifier
-QT = core-private testlib
-SOURCES = tst_qwinoverlappedionotifier.cpp
diff --git a/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp b/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp
deleted file mode 100644
index 7034c2c9fd..0000000000
--- a/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <private/qwinoverlappedionotifier_p.h>
-#include <qbytearray.h>
-#include <qt_windows.h>
-
-#ifndef PIPE_REJECT_REMOTE_CLIENTS
-#define PIPE_REJECT_REMOTE_CLIENTS 0x08
-#endif
-
-class tst_QWinOverlappedIoNotifier : public QObject
-{
- Q_OBJECT
-
-private slots:
- void initTestCase();
- void readFile_data();
- void readFile();
- void waitForNotified_data();
- void waitForNotified();
- void waitForAnyNotified();
- void brokenPipe();
- void multipleOperations();
-
-private:
- QFileInfo sourceFileInfo;
- DWORD notifiedBytesRead;
- DWORD notifiedErrorCode;
-};
-
-class NotifierSink : public QObject
-{
- Q_OBJECT
-public:
- NotifierSink(QWinOverlappedIoNotifier *notifier)
- : QObject(notifier),
- threshold(1)
- {
- connect(notifier, &QWinOverlappedIoNotifier::notified, this, &NotifierSink::notified);
- }
-
-protected slots:
- void notified(DWORD bytesRead, DWORD errorCode, OVERLAPPED *overlapped)
- {
- IOResult ioResult;
- ioResult.bytes = bytesRead;
- ioResult.errorCode = errorCode;
- ioResult.overlapped = overlapped;
- notifications.append(ioResult);
- if (notifications.count() >= threshold)
- emit notificationReceived();
- }
-
-signals:
- void notificationReceived();
-
-public:
- int threshold;
-
- struct IOResult
- {
- IOResult()
- : bytes(0), errorCode(ERROR_SUCCESS), overlapped(0)
- {}
- DWORD bytes;
- DWORD errorCode;
- OVERLAPPED *overlapped;
- };
-
- QList<IOResult> notifications;
-};
-
-void tst_QWinOverlappedIoNotifier::initTestCase()
-{
- sourceFileInfo.setFile(QFINDTESTDATA("tst_qwinoverlappedionotifier.cpp"));
- QVERIFY2(sourceFileInfo.exists(), "File tst_qwinoverlappedionotifier.cpp not found.");
-}
-
-void tst_QWinOverlappedIoNotifier::readFile_data()
-{
- QTest::addColumn<QString>("fileName");
- QTest::addColumn<int>("readBufferSize");
- QTest::addColumn<DWORD>("expectedBytesRead");
-
- QString sourceFileName = QDir::toNativeSeparators(sourceFileInfo.absoluteFilePath());
- int sourceFileSize = sourceFileInfo.size();
-
- QTest::newRow("read file, less than available")
- << sourceFileName << sourceFileSize / 2 << DWORD(sourceFileSize / 2);
- QTest::newRow("read file, more than available")
- << sourceFileName << sourceFileSize * 2 << DWORD(sourceFileSize);
-}
-
-void tst_QWinOverlappedIoNotifier::readFile()
-{
- QFETCH(QString, fileName);
- QFETCH(int, readBufferSize);
- QFETCH(DWORD, expectedBytesRead);
-
- QWinOverlappedIoNotifier notifier;
- NotifierSink sink(&notifier);
- connect(&sink, &NotifierSink::notificationReceived, &QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
-
- HANDLE hFile = CreateFile(reinterpret_cast<const wchar_t*>(fileName.utf16()),
- GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- notifier.setHandle(hFile);
- notifier.setEnabled(true);
-
- OVERLAPPED overlapped;
- ZeroMemory(&overlapped, sizeof(OVERLAPPED));
- QByteArray buffer(readBufferSize, 0);
- BOOL readSuccess = ReadFile(hFile, buffer.data(), buffer.size(), NULL, &overlapped);
- QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING);
-
- QTestEventLoop::instance().enterLoop(3);
- CloseHandle(hFile);
- QCOMPARE(sink.notifications.count(), 1);
- QCOMPARE(sink.notifications.last().bytes, expectedBytesRead);
- QCOMPARE(sink.notifications.last().errorCode, DWORD(ERROR_SUCCESS));
- QCOMPARE(sink.notifications.last().overlapped, &overlapped);
-}
-
-void tst_QWinOverlappedIoNotifier::waitForNotified_data()
-{
- readFile_data();
-}
-
-void tst_QWinOverlappedIoNotifier::waitForNotified()
-{
- QFETCH(QString, fileName);
- QFETCH(int, readBufferSize);
- QFETCH(DWORD, expectedBytesRead);
-
- QWinOverlappedIoNotifier notifier;
- NotifierSink sink(&notifier);
- HANDLE hFile = CreateFile(reinterpret_cast<const wchar_t*>(fileName.utf16()),
- GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- notifier.setHandle(hFile);
- notifier.setEnabled(true);
- QCOMPARE(notifier.waitForNotified(100, 0), false);
-
- OVERLAPPED overlapped;
- ZeroMemory(&overlapped, sizeof(OVERLAPPED));
- QByteArray buffer(readBufferSize, 0);
- BOOL readSuccess = ReadFile(hFile, buffer.data(), buffer.size(), NULL, &overlapped);
- QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING);
-
- QCOMPARE(notifier.waitForNotified(3000, &overlapped), true);
- CloseHandle(hFile);
- QCOMPARE(sink.notifications.count(), 1);
- QCOMPARE(sink.notifications.last().bytes, expectedBytesRead);
- QCOMPARE(sink.notifications.last().errorCode, DWORD(ERROR_SUCCESS));
- QCOMPARE(sink.notifications.last().overlapped, &overlapped);
- QCOMPARE(notifier.waitForNotified(100, &overlapped), false);
-}
-
-void tst_QWinOverlappedIoNotifier::waitForAnyNotified()
-{
- const QString fileName = QDir::toNativeSeparators(sourceFileInfo.absoluteFilePath());
- const int readBufferSize = sourceFileInfo.size();
-
- QWinOverlappedIoNotifier notifier;
- HANDLE hFile = CreateFile(reinterpret_cast<const wchar_t*>(fileName.utf16()),
- GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- notifier.setHandle(hFile);
- notifier.setEnabled(true);
- QVERIFY(!notifier.waitForAnyNotified(100));
-
- OVERLAPPED overlapped1;
- ZeroMemory(&overlapped1, sizeof(OVERLAPPED));
- QByteArray buffer1(readBufferSize, 0);
- BOOL readSuccess = ReadFile(hFile, buffer1.data(), buffer1.size(), NULL, &overlapped1);
- QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING);
-
- OVERLAPPED overlapped2;
- ZeroMemory(&overlapped2, sizeof(OVERLAPPED));
- QByteArray buffer2(readBufferSize, 0);
- readSuccess = ReadFile(hFile, buffer2.data(), buffer2.size(), NULL, &overlapped2);
- QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING);
-
- QSet<OVERLAPPED *> overlappedObjects;
- overlappedObjects << &overlapped1 << &overlapped2;
-
- for (int i = 1; i <= 2; ++i) {
- OVERLAPPED *notifiedOverlapped = notifier.waitForAnyNotified(3000);
- QVERIFY(overlappedObjects.contains(notifiedOverlapped));
- overlappedObjects.remove(notifiedOverlapped);
- }
-
- CloseHandle(hFile);
- QVERIFY(overlappedObjects.isEmpty());
- QVERIFY(!notifier.waitForAnyNotified(100));
-}
-
-void tst_QWinOverlappedIoNotifier::brokenPipe()
-{
- QWinOverlappedIoNotifier notifier;
- NotifierSink sink(&notifier);
- connect(&sink, &NotifierSink::notificationReceived, &QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
-
- wchar_t pipeName[] = L"\\\\.\\pipe\\tst_QWinOverlappedIoNotifier_brokenPipe";
- HANDLE hPipe = CreateNamedPipe(pipeName,
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_BYTE | PIPE_NOWAIT | PIPE_REJECT_REMOTE_CLIENTS,
- 1, 0, 0, 0, NULL);
- QVERIFY(hPipe != INVALID_HANDLE_VALUE);
- HANDLE hReadEnd = CreateFile(pipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
- QVERIFY(hReadEnd != INVALID_HANDLE_VALUE);
- notifier.setHandle(hReadEnd);
- notifier.setEnabled(true);
-
- OVERLAPPED overlapped;
- ZeroMemory(&overlapped, sizeof(OVERLAPPED));
- QByteArray buffer(1024, 0);
- BOOL readSuccess = ReadFile(hReadEnd, buffer.data(), buffer.size(), NULL, &overlapped);
- QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING);
-
- // close the write end of the pipe
- CloseHandle(hPipe);
-
- QTestEventLoop::instance().enterLoop(3);
- CloseHandle(hReadEnd);
- QCOMPARE(sink.notifications.count(), 1);
- QCOMPARE(sink.notifications.last().bytes, DWORD(0));
- QCOMPARE(sink.notifications.last().errorCode, DWORD(ERROR_BROKEN_PIPE));
- QCOMPARE(sink.notifications.last().overlapped, &overlapped);
-}
-
-void tst_QWinOverlappedIoNotifier::multipleOperations()
-{
- QWinOverlappedIoNotifier clientNotifier;
- NotifierSink sink(&clientNotifier);
- sink.threshold = 2;
- connect(&sink, &NotifierSink::notificationReceived,
- &QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
-
- wchar_t pipeName[] = L"\\\\.\\pipe\\tst_QWinOverlappedIoNotifier_multipleOperations";
- HANDLE hServer = CreateNamedPipe(pipeName,
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_BYTE | PIPE_NOWAIT | PIPE_REJECT_REMOTE_CLIENTS,
- 1, 0, 0, 0, NULL);
- QVERIFY(hServer != INVALID_HANDLE_VALUE);
- HANDLE hClient = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
- QVERIFY(hClient != INVALID_HANDLE_VALUE);
- clientNotifier.setHandle(hClient);
- clientNotifier.setEnabled(true);
-
- // start async read on client
- QByteArray clientReadBuffer(377, Qt::Uninitialized);
- OVERLAPPED clientReadOverlapped;
- ZeroMemory(&clientReadOverlapped, sizeof(clientReadOverlapped));
- BOOL readSuccess = ReadFile(hClient, clientReadBuffer.data(), clientReadBuffer.size(),
- NULL, &clientReadOverlapped);
- QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING);
-
- // start async write client -> server
- QByteArray clientDataToWrite(233, 'B');
- OVERLAPPED clientWriteOverlapped;
- ZeroMemory(&clientWriteOverlapped, sizeof(clientWriteOverlapped));
- BOOL writeSuccess = WriteFile(hClient, clientDataToWrite.data(), clientDataToWrite.size(),
- NULL, &clientWriteOverlapped);
- QVERIFY(writeSuccess || GetLastError() == ERROR_IO_PENDING);
-
- // start async write server -> client
- QByteArray serverDataToWrite(144, 'A');
- OVERLAPPED serverOverlapped;
- ZeroMemory(&serverOverlapped, sizeof(serverOverlapped));
- writeSuccess = WriteFile(hServer, serverDataToWrite.data(), serverDataToWrite.size(),
- NULL, &serverOverlapped);
- QVERIFY(writeSuccess || GetLastError() == ERROR_IO_PENDING);
-
- // read synchronously on server to complete the client -> server write
- QByteArray serverReadBuffer(610, Qt::Uninitialized);
- DWORD dwBytesRead = 0;
- readSuccess = ReadFile(hServer, serverReadBuffer.data(), serverReadBuffer.size(),
- &dwBytesRead, NULL);
- QVERIFY(readSuccess);
- QCOMPARE(int(dwBytesRead), clientDataToWrite.size());
- serverReadBuffer.resize(dwBytesRead);
- QCOMPARE(serverReadBuffer, clientDataToWrite);
-
- QTestEventLoop::instance().enterLoop(3);
- QTRY_COMPARE(sink.notifications.count(), 2);
- foreach (const NotifierSink::IOResult &r, sink.notifications) {
- QCOMPARE(r.errorCode, DWORD(ERROR_SUCCESS));
- if (r.bytes == DWORD(serverDataToWrite.count()))
- QCOMPARE(r.overlapped, &clientReadOverlapped);
- else if (r.bytes == DWORD(clientDataToWrite.count()))
- QCOMPARE(r.overlapped, &clientWriteOverlapped);
- else
- QVERIFY2(false, "Unexpected number of bytes received.");
- }
-
- CloseHandle(hClient);
- CloseHandle(hServer);
-}
-
-QTEST_MAIN(tst_QWinOverlappedIoNotifier)
-
-#include "tst_qwinoverlappedionotifier.moc"