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/largefile/tst_largefile.cpp4
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp15
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp41
-rw-r--r--tests/auto/corelib/io/qfile/BLACKLIST4
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp30
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp464
-rw-r--r--tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp6
-rw-r--r--tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp91
-rw-r--r--tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp10
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp6
-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/qsavefile/tst_qsavefile.cpp60
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp76
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp32
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp85
-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
21 files changed, 777 insertions, 663 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/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp
index 5975303ca6..2d13e6166d 100644
--- a/tests/auto/corelib/io/largefile/tst_largefile.cpp
+++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp
@@ -31,6 +31,7 @@
#include <QtAlgorithms>
#include <QFile>
#include <QFileInfo>
+#include <QRandomGenerator>
#include <qplatformdefs.h>
#include <QDebug>
@@ -174,8 +175,7 @@ static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 u
static qint64 counter = 0;
- qint64 randomBits = ((qint64)qrand() << 32)
- | ((qint64)qrand() & 0x00000000ffffffff);
+ qint64 randomBits = QRandomGenerator::global()->generate64();
appendRaw(block, randomBits);
appendRaw(block, userBits);
diff --git a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
index ddfd14550b..1072cb44f9 100644
--- a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
+++ b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
@@ -341,8 +341,10 @@ public:
if (file) {
QMutexLocker lock(&file->mutex);
switch (time) {
- case CreationTime:
- return file->creation;
+ case BirthTime:
+ return file->birth;
+ case MetadataChangeTime:
+ return file->change;
case ModificationTime:
return file->modification;
case AccessTime:
@@ -353,6 +355,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_)
@@ -449,7 +458,7 @@ protected:
uint userId, groupId;
QAbstractFileEngine::FileFlags fileFlags;
- QDateTime creation, modification, access;
+ QDateTime birth, change, modification, access;
QByteArray content;
};
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/BLACKLIST b/tests/auto/corelib/io/qfile/BLACKLIST
index 8d636d40b8..8366667166 100644
--- a/tests/auto/corelib/io/qfile/BLACKLIST
+++ b/tests/auto/corelib/io/qfile/BLACKLIST
@@ -5,7 +5,3 @@ msvc-2017 ci
[readLineStdin_lineByLine]
msvc-2015 ci
msvc-2017 ci
-[openStandardStreamsFileDescriptors]
-osx
-[openStandardStreamsBufferedStreams]
-osx
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 5f0eae6fc3..c173a87a41 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -2138,6 +2138,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;
@@ -3247,22 +3248,39 @@ static qint64 streamExpectedSize(int fd)
QT_STATBUF sb;
if (QT_FSTAT(fd, &sb) != -1)
return sb.st_size;
+ qErrnoWarning("Could not fstat fd %d", fd);
return 0;
}
static qint64 streamCurrentPosition(int fd)
{
- QT_OFF_T pos = QT_LSEEK(fd, 0, SEEK_CUR);
- if (pos != -1)
- return pos;
+ QT_STATBUF sb;
+ if (QT_FSTAT(fd, &sb) != -1) {
+ QT_OFF_T pos = -1;
+ if ((sb.st_mode & QT_STAT_MASK) == QT_STAT_REG)
+ pos = QT_LSEEK(fd, 0, SEEK_CUR);
+ if (pos != -1)
+ return pos;
+ // failure to lseek() is not a problem
+ } else {
+ qErrnoWarning("Could not fstat fd %d", fd);
+ }
return 0;
}
static qint64 streamCurrentPosition(FILE *f)
{
- QT_OFF_T pos = QT_FTELL(f);
- if (pos != -1)
- return pos;
+ QT_STATBUF sb;
+ if (QT_FSTAT(QT_FILENO(f), &sb) != -1) {
+ QT_OFF_T pos = -1;
+ if ((sb.st_mode & QT_STAT_MASK) == QT_STAT_REG)
+ pos = QT_FTELL(f);
+ if (pos != -1)
+ return pos;
+ // failure to ftell() is not a problem
+ } else {
+ qErrnoWarning("Could not fstat fd %d", QT_FILENO(f));
+ }
return 0;
}
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index f35dab2cad..44e79985d4 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -35,6 +35,7 @@
#include <qtemporarydir.h>
#include <qdir.h>
#include <qfileinfo.h>
+#include <qstorageinfo.h>
#ifdef Q_OS_UNIX
#include <errno.h>
#include <fcntl.h>
@@ -47,7 +48,6 @@
#endif
#ifdef Q_OS_WIN
#include <qt_windows.h>
-#include <qlibrary.h>
#if !defined(Q_OS_WINRT)
#include <lm.h>
#endif
@@ -64,84 +64,38 @@
#define Q_NO_SYMLINKS
#endif
-
-#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
-inline bool qt_isEvilFsTypeName(const char *name)
-{
- return (qstrncmp(name, "nfs", 3) == 0
- || qstrncmp(name, "autofs", 6) == 0
- || qstrncmp(name, "cachefs", 7) == 0);
-}
-
-#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
-# include <sys/param.h>
-# include <sys/mount.h>
-
-bool qIsLikelyToBeNfs(int handle)
-{
- struct statfs buf;
- if (fstatfs(handle, &buf) != 0)
- return false;
- return qt_isEvilFsTypeName(buf.f_fstypename);
-}
-
-#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
-
-# include <sys/vfs.h>
-# ifdef QT_LINUXBASE
- // LSB 3.2 has fstatfs in sys/statfs.h, sys/vfs.h is just an empty dummy header
-# include <sys/statfs.h>
-# endif
-
-# ifndef NFS_SUPER_MAGIC
-# define NFS_SUPER_MAGIC 0x00006969
-# endif
-# ifndef AUTOFS_SUPER_MAGIC
-# define AUTOFS_SUPER_MAGIC 0x00000187
-# endif
-# ifndef AUTOFSNG_SUPER_MAGIC
-# define AUTOFSNG_SUPER_MAGIC 0x7d92b1a0
-# endif
-
-bool qIsLikelyToBeNfs(int handle)
+inline bool qIsLikelyToBeFat(const QString &path)
{
- struct statfs buf;
- if (fstatfs(handle, &buf) != 0)
- return false;
- return buf.f_type == NFS_SUPER_MAGIC
- || buf.f_type == AUTOFS_SUPER_MAGIC
- || buf.f_type == AUTOFSNG_SUPER_MAGIC;
+ QByteArray name = QStorageInfo(path).fileSystemType().toLower();
+ return name.contains("fat") || name.contains("msdos");
}
-#elif defined(Q_OS_SOLARIS) || defined(Q_OS_IRIX) || defined(Q_OS_AIX) || defined(Q_OS_HPUX) \
- || defined(Q_OS_OSF) || defined(Q_OS_QNX) || defined(Q_OS_SCO) \
- || defined(Q_OS_UNIXWARE) || defined(Q_OS_RELIANT) || defined(Q_OS_NETBSD)
-
-# include <sys/statvfs.h>
-
-bool qIsLikelyToBeNfs(int handle)
+inline bool qIsLikelyToBeNfs(const QString &path)
{
- struct statvfs buf;
- if (fstatvfs(handle, &buf) != 0)
- return false;
-#if defined(Q_OS_NETBSD)
- return qt_isEvilFsTypeName(buf.f_fstypename);
+#ifdef Q_OS_WIN
+ Q_UNUSED(path);
+ return false;
#else
- return qt_isEvilFsTypeName(buf.f_basetype);
+ QByteArray type = QStorageInfo(path).fileSystemType();
+ const char *name = type.constData();
+
+ return (qstrncmp(name, "nfs", 3) == 0
+ || qstrncmp(name, "autofs", 6) == 0
+ || qstrncmp(name, "autofsng", 8) == 0
+ || qstrncmp(name, "cachefs", 7) == 0);
#endif
}
-#else
-inline bool qIsLikelyToBeNfs(int /* handle */)
-{
- return false;
-}
-#endif
-#endif
static QString seedAndTemplate()
{
- qsrand(QDateTime::currentSecsSinceEpoch());
- return QDir::tempPath() + "/tst_qfileinfo-XXXXXX";
+ QString base;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
+ // use XDG_RUNTIME_DIR as it's a fully-capable FS
+ base = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+#endif
+ if (base.isEmpty())
+ base = QDir::tempPath();
+ return base + "/tst_qfileinfo-XXXXXX";
}
static QByteArray msgDoesNotExist(const QString &name)
@@ -277,8 +231,9 @@ private slots:
#endif
void group();
+ void invalidState_data();
void invalidState();
- void nonExistingFileDates();
+ void nonExistingFile();
private:
const QString m_currentDir;
@@ -728,18 +683,12 @@ void tst_QFileInfo::canonicalFilePath()
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD);
- PtrCreateSymbolicLink ptrCreateSymbolicLink =
- (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLinkW");
-
- if (!ptrCreateSymbolicLink) {
- QSKIP("Symbolic links aren't supported by FS");
- } else {
+ {
// CreateSymbolicLink can return TRUE & still fail to create the link,
// the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314)
SetLastError(0);
const QString linkTarget = QStringLiteral("res");
- BOOL ret = ptrCreateSymbolicLink((wchar_t*)linkTarget.utf16(), (wchar_t*)m_resourcesDir.utf16(), 1);
+ BOOL ret = CreateSymbolicLink((wchar_t*)linkTarget.utf16(), (wchar_t*)m_resourcesDir.utf16(), 1);
DWORD dwErr = GetLastError();
if (!ret)
QSKIP("Symbolic links aren't supported by FS");
@@ -1034,6 +983,11 @@ void tst_QFileInfo::systemFiles()
QVERIFY2(fi.exists(), msgDoesNotExist(fi.absoluteFilePath()).constData());
QVERIFY(fi.size() > 0);
QVERIFY(fi.lastModified().isValid());
+ QVERIFY(fi.metadataChangeTime().isValid());
+ QCOMPARE(fi.metadataChangeTime(), fi.lastModified()); // On Windows, they're the same
+ QVERIFY(fi.birthTime().isValid());
+ QVERIFY(fi.birthTime() <= fi.lastModified());
+ QCOMPARE(fi.created(), fi.birthTime()); // On Windows, they're the same
}
void tst_QFileInfo::compare_data()
@@ -1124,43 +1078,92 @@ void tst_QFileInfo::fileTimes_data()
void tst_QFileInfo::fileTimes()
{
- int sleepTime = 2000;
+ auto datePairString = [](const QDateTime &actual, const QDateTime &before) {
+ return (actual.toString(Qt::ISODateWithMs) + " (should be >) " + before.toString(Qt::ISODateWithMs))
+ .toLatin1();
+ };
+
QFETCH(QString, fileName);
+ int sleepTime = 100;
+
+ // on Linux and Windows, the filesystem timestamps may be slightly out of
+ // sync with the system clock (maybe they're using CLOCK_REALTIME_COARSE),
+ // so add a margin of error to our comparisons
+ int fsClockSkew = 10;
+#ifdef Q_OS_WIN
+ fsClockSkew = 500;
+#endif
+
+ // NFS clocks may be WAY out of sync
+ if (qIsLikelyToBeNfs(fileName))
+ QSKIP("This test doesn't work on NFS");
+
+ bool noAccessTime = false;
+ {
+ // try to guess if file times on this filesystem round to the second
+ QFileInfo cwd(".");
+ if (cwd.lastModified().toMSecsSinceEpoch() % 1000 == 0
+ && cwd.lastRead().toMSecsSinceEpoch() % 1000 == 0) {
+ fsClockSkew = sleepTime = 1000;
+
+ noAccessTime = qIsLikelyToBeFat(fileName);
+ if (noAccessTime) {
+ // FAT filesystems (but maybe not exFAT) store timestamps with 2-second
+ // granularity and access time with 1-day granularity
+ fsClockSkew = sleepTime = 2000;
+ }
+ }
+ }
+
if (QFile::exists(fileName)) {
QVERIFY(QFile::remove(fileName));
}
- QTest::qSleep(sleepTime);
+
+ QDateTime beforeBirth, beforeWrite, beforeMetadataChange, beforeRead;
+ QDateTime birthTime, writeTime, metadataChangeTime, readTime;
+
+ // --- Create file and write to it
+ beforeBirth = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
{
QFile file(fileName);
QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
-#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
- if (qIsLikelyToBeNfs(file.handle()))
- QSKIP("This Test doesn't work on NFS");
-#endif
+ QFileInfo fileInfo(fileName);
+ birthTime = fileInfo.birthTime();
+ QVERIFY2(!birthTime.isValid() || birthTime > beforeBirth,
+ datePairString(birthTime, beforeBirth));
+
+ QTest::qSleep(sleepTime);
+ beforeWrite = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
QTextStream ts(&file);
ts << fileName << endl;
}
- QTest::qSleep(sleepTime);
- QDateTime beforeWrite = QDateTime::currentDateTime();
- QTest::qSleep(sleepTime);
{
QFileInfo fileInfo(fileName);
- QVERIFY(fileInfo.created() < beforeWrite);
- QFile file(fileName);
- QVERIFY(file.open(QFile::ReadWrite | QFile::Text));
- QTextStream ts(&file);
- ts << fileName << endl;
+ writeTime = fileInfo.lastModified();
+ QVERIFY2(writeTime > beforeWrite, datePairString(writeTime, beforeWrite));
+ QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed
}
+
+ // --- Change the file's metadata
QTest::qSleep(sleepTime);
- QDateTime beforeRead = QDateTime::currentDateTime();
- QTest::qSleep(sleepTime);
+ beforeMetadataChange = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
+ {
+ QFile file(fileName);
+ file.setPermissions(file.permissions());
+ }
{
QFileInfo fileInfo(fileName);
-// On unix created() returns the same as lastModified().
-#if !defined(Q_OS_UNIX)
- QVERIFY(fileInfo.created() < beforeWrite);
-#endif
- QVERIFY(fileInfo.lastModified() > beforeWrite);
+ metadataChangeTime = fileInfo.metadataChangeTime();
+ QVERIFY2(metadataChangeTime > beforeMetadataChange,
+ datePairString(metadataChangeTime, beforeMetadataChange));
+ QVERIFY(metadataChangeTime >= writeTime); // not all filesystems can store both times
+ QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed
+ }
+
+ // --- Read the file
+ QTest::qSleep(sleepTime);
+ beforeRead = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
+ {
QFile file(fileName);
QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
QTextStream ts(&file);
@@ -1169,13 +1172,17 @@ void tst_QFileInfo::fileTimes()
}
QFileInfo fileInfo(fileName);
-#if !defined(Q_OS_UNIX)
- QVERIFY(fileInfo.created() < beforeWrite);
-#endif
+ readTime = fileInfo.lastRead();
+ QCOMPARE(fileInfo.lastModified(), writeTime); // mustn't have changed
+ QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed
+ QVERIFY(readTime.isValid());
+
+#if defined(Q_OS_WINRT) || defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
+ noAccessTime = true;
+#elif defined(Q_OS_WIN)
//In Vista the last-access timestamp is not updated when the file is accessed/touched (by default).
//To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
//is set to 0, in the test machine.
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
HKEY key;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\FileSystem",
0, KEY_READ, &key)) {
@@ -1184,75 +1191,43 @@ void tst_QFileInfo::fileTimes()
LONG error = RegQueryValueEx(key, L"NtfsDisableLastAccessUpdate"
, NULL, NULL, (LPBYTE)&disabledAccessTimes, &size);
if (ERROR_SUCCESS == error && disabledAccessTimes)
- QEXPECT_FAIL("", "File access times are disabled in windows registry (this is the default setting)", Continue);
+ noAccessTime = true;
RegCloseKey(key);
}
#endif
-#if defined(Q_OS_WINRT)
- QEXPECT_FAIL("", "WinRT does not allow timestamp handling change in the filesystem due to sandboxing", Continue);
-#elif defined(Q_OS_QNX)
- QEXPECT_FAIL("", "QNX uses the noatime filesystem option", Continue);
-#elif defined(Q_OS_ANDROID)
- if (fileInfo.lastRead() <= beforeRead)
- QEXPECT_FAIL("", "Android may use relatime or noatime on mounts", Continue);
-#endif
- QVERIFY(fileInfo.lastRead() > beforeRead);
- QVERIFY(fileInfo.lastModified() > beforeWrite);
- QVERIFY(fileInfo.lastModified() < beforeRead);
+ if (noAccessTime)
+ return;
+
+ QVERIFY2(readTime > beforeRead, datePairString(readTime, beforeRead));
+ QVERIFY(writeTime < beforeRead);
}
void tst_QFileInfo::fileTimes_oldFile()
{
- // This is not supported on WinRT
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- // All files are opened in share mode (both read and write).
- DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-
- // All files on Windows can be read; there's no such thing as an
- // unreadable file. Add GENERIC_WRITE if WriteOnly is passed.
- int accessRights = GENERIC_READ | GENERIC_WRITE;
-
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
-
- // Regular file mode. In Unbuffered mode, pass the no-buffering flag.
- DWORD flagsAndAtts = FILE_ATTRIBUTE_NORMAL;
-
- // WriteOnly can create files, ReadOnly cannot.
- DWORD creationDisp = OPEN_ALWAYS;
-
- // Create the file handle.
- HANDLE fileHandle = CreateFile(L"oldfile.txt",
- accessRights,
- shareMode,
- &securityAtts,
- creationDisp,
- flagsAndAtts,
- NULL);
-
- // Set file times back to 1601.
- SYSTEMTIME stime;
- stime.wYear = 1601;
- stime.wMonth = 1;
- stime.wDayOfWeek = 1;
- stime.wDay = 1;
- stime.wHour = 1;
- stime.wMinute = 0;
- stime.wSecond = 0;
- stime.wMilliseconds = 0;
-
- FILETIME ctime;
- QVERIFY(SystemTimeToFileTime(&stime, &ctime));
- FILETIME atime = ctime;
- FILETIME mtime = atime;
- QVERIFY(fileHandle);
- QVERIFY(SetFileTime(fileHandle, &ctime, &atime, &mtime) != 0);
-
- CloseHandle(fileHandle);
-
- QFileInfo info("oldfile.txt");
- QCOMPARE(info.lastModified(), QDateTime(QDate(1601, 1, 1), QTime(1, 0), Qt::UTC).toLocalTime());
-#endif
+ // This is 2^{31} seconds before 1970-01-01 15:14:8,
+ // i.e. shortly after the start of time_t, in any time-zone:
+ const QDateTime early(QDate(1901, 12, 14), QTime(12, 0));
+ QFile file("ancientfile.txt");
+ file.open(QIODevice::WriteOnly);
+ file.write("\n", 1);
+ file.close();
+
+ /*
+ QFile's setFileTime calls QFSFileEngine::setFileTime() which fails unless
+ the file is open at the time. Of course, when writing, close() changes
+ modification time, so need to re-open for read in order to setFileTime().
+ */
+ file.open(QIODevice::ReadOnly);
+ bool ok = file.setFileTime(early, QFileDevice::FileModificationTime);
+ file.close();
+
+ if (ok) {
+ QFileInfo info(file.fileName());
+ QCOMPARE(info.lastModified(), early);
+ } else {
+ QSKIP("Unable to set file metadata to ancient values");
+ }
}
void tst_QFileInfo::isSymLink_data()
@@ -1392,7 +1367,7 @@ void tst_QFileInfo::isNativePath_data()
QTest::addColumn<bool>("isNativePath");
QTest::newRow("default-constructed") << QString() << false;
- QTest::newRow("empty") << QString("") << true;
+ QTest::newRow("empty") << QString("") << false;
QTest::newRow("local root") << QString::fromLatin1("/") << true;
QTest::newRow("local non-existent file") << QString::fromLatin1("/abrakadabra.boo") << true;
@@ -1461,16 +1436,6 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QDir pwd;
pwd.mkdir("target");
- QLibrary kernel32("kernel32");
- typedef BOOLEAN (WINAPI *PtrCreateSymbolicLink)(LPCWSTR, LPCWSTR, DWORD);
- PtrCreateSymbolicLink createSymbolicLinkW = 0;
- createSymbolicLinkW = (PtrCreateSymbolicLink) kernel32.resolve("CreateSymbolicLinkW");
- if (!createSymbolicLinkW) {
- //we need at least one data set for the test not to fail when skipping _data function
- QDir target("target");
- QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath();
- QSKIP("symbolic links not supported by operating system");
- }
{
//Directory symlinks
QDir target("target");
@@ -1490,10 +1455,10 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
DWORD err = ERROR_SUCCESS ;
if (!pwd.exists("abs_symlink"))
- if (!createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1))
+ if (!CreateSymbolicLink((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1))
err = GetLastError();
if (err == ERROR_SUCCESS && !pwd.exists(relSymlink))
- if (!createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1))
+ if (!CreateSymbolicLink((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1))
err = GetLastError();
if (err != ERROR_SUCCESS) {
wchar_t errstr[0x100];
@@ -1523,10 +1488,9 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString relSymlink = "rel_symlink.cpp";
QString relToRelTarget = QDir::toNativeSeparators(relativeDir.relativeFilePath(target.absoluteFilePath()));
QString relToRelSymlink = "relative/rel_symlink";
- QVERIFY(pwd.exists("abs_symlink.cpp") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0));
- QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0));
- QVERIFY(pwd.exists(relToRelSymlink)
- || createSymbolicLinkW((wchar_t*)relToRelSymlink.utf16(), (wchar_t*)relToRelTarget.utf16(),0x0));
+ QVERIFY(pwd.exists("abs_symlink.cpp") || CreateSymbolicLink((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0));
+ QVERIFY(pwd.exists(relSymlink) || CreateSymbolicLink((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0));
+ QVERIFY(pwd.exists(relToRelSymlink) || CreateSymbolicLink((wchar_t*)relToRelSymlink.utf16(), (wchar_t*)relToRelTarget.utf16(),0x0));
QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
QTest::newRow("relative to relative file symlink") << relToRelSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
@@ -1553,20 +1517,14 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QTest::newRow("junction_root") << junction << false << QString() << QString();
//Mountpoint
- typedef BOOLEAN (WINAPI *PtrGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD);
- PtrGetVolumeNameForVolumeMountPointW getVolumeNameForVolumeMountPointW = 0;
- getVolumeNameForVolumeMountPointW = (PtrGetVolumeNameForVolumeMountPointW) kernel32.resolve("GetVolumeNameForVolumeMountPointW");
- if(getVolumeNameForVolumeMountPointW)
- {
- wchar_t buffer[MAX_PATH];
- QString rootPath = QDir::toNativeSeparators(QDir::rootPath());
- QVERIFY(getVolumeNameForVolumeMountPointW((wchar_t*)rootPath.utf16(), buffer, MAX_PATH));
- QString rootVolume = QString::fromWCharArray(buffer);
- junction = "mountpoint";
- rootVolume.replace("\\\\?\\","\\??\\");
- FileSystem::createNtfsJunction(rootVolume, junction);
- QTest::newRow("mountpoint") << junction << false << QString() << QString();
- }
+ wchar_t buffer[MAX_PATH];
+ QString rootPath = QDir::toNativeSeparators(QDir::rootPath());
+ QVERIFY(GetVolumeNameForVolumeMountPoint((wchar_t*)rootPath.utf16(), buffer, MAX_PATH));
+ QString rootVolume = QString::fromWCharArray(buffer);
+ junction = "mountpoint";
+ rootVolume.replace("\\\\?\\","\\??\\");
+ FileSystem::createNtfsJunction(rootVolume, junction);
+ QTest::newRow("mountpoint") << junction << false << QString() << QString();
}
void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
@@ -1928,56 +1886,96 @@ void tst_QFileInfo::group()
QCOMPARE(fi.group(), expected);
}
-void tst_QFileInfo::invalidState()
+static void stateCheck(const QFileInfo &info, const QString &dirname, const QString &filename)
{
- // Shouldn't crash;
-
- {
- QFileInfo info;
- QCOMPARE(info.size(), qint64(0));
- QVERIFY(!info.exists());
-
- info.setCaching(false);
+ QCOMPARE(info.size(), qint64(0));
+ QVERIFY(!info.exists());
- info.created();
- info.lastRead();
- info.lastModified();
+ QString path;
+ QString abspath;
+ if (!dirname.isEmpty()) {
+ path = ".";
+ abspath = dirname + '/' + filename;
}
- {
- QFileInfo info("");
- QCOMPARE(info.size(), qint64(0));
- QVERIFY(!info.exists());
-
- info.setCaching(false);
+ QCOMPARE(info.filePath(), filename);
+ QCOMPARE(info.absoluteFilePath(), abspath);
+ QCOMPARE(info.canonicalFilePath(), QString());
+ QCOMPARE(info.fileName(), filename);
+ QCOMPARE(info.baseName(), filename);
+ QCOMPARE(info.completeBaseName(), filename);
+ QCOMPARE(info.suffix(), QString());
+ QCOMPARE(info.bundleName(), QString());
+ QCOMPARE(info.completeSuffix(), QString());
+
+ QVERIFY(info.isRelative());
+ QCOMPARE(info.path(), path);
+ QCOMPARE(info.absolutePath(), dirname);
+ QCOMPARE(info.dir().path(), ".");
+
+ // these don't look right
+ QCOMPARE(info.canonicalPath(), path);
+ QCOMPARE(info.absoluteDir().path(), dirname.isEmpty() ? "." : dirname);
+
+ QVERIFY(!info.isReadable());
+ QVERIFY(!info.isWritable());
+ QVERIFY(!info.isExecutable());
+ QVERIFY(!info.isHidden());
+ QVERIFY(!info.isFile());
+ QVERIFY(!info.isDir());
+ QVERIFY(!info.isSymLink());
+ QVERIFY(!info.isBundle());
+ QVERIFY(!info.isRoot());
+ QCOMPARE(info.isNativePath(), !filename.isEmpty());
+
+ QCOMPARE(info.readLink(), QString());
+ QCOMPARE(info.ownerId(), uint(-2));
+ QCOMPARE(info.groupId(), uint(-2));
+ QCOMPARE(info.owner(), QString());
+ QCOMPARE(info.group(), QString());
+
+ QCOMPARE(info.permissions(), QFile::Permissions());
- info.created();
- info.lastRead();
- info.lastModified();
- }
+ QVERIFY(!info.created().isValid());
+ QVERIFY(!info.birthTime().isValid());
+ QVERIFY(!info.metadataChangeTime().isValid());
+ QVERIFY(!info.lastRead().isValid());
+ QVERIFY(!info.lastModified().isValid());
+};
- {
- QFileInfo info("file-doesn't-really-exist.txt");
- QCOMPARE(info.size(), qint64(0));
- QVERIFY(!info.exists());
+void tst_QFileInfo::invalidState_data()
+{
+ QTest::addColumn<int>("mode");
+ QTest::newRow("default") << 0;
+ QTest::newRow("empty") << 1;
+ QTest::newRow("copy-of-default") << 2;
+ QTest::newRow("copy-of-empty") << 3;
+}
- info.setCaching(false);
+void tst_QFileInfo::invalidState()
+{
+ // Shouldn't crash or produce warnings
+ QFETCH(int, mode);
+ const QFileInfo &info = (mode & 1 ? QFileInfo("") : QFileInfo());
- info.created();
- info.lastRead();
- info.lastModified();
+ if (mode & 2) {
+ QFileInfo copy(info);
+ stateCheck(copy, QString(), QString());
+ } else {
+ stateCheck(info, QString(), QString());
}
-
- QVERIFY(true);
}
-void tst_QFileInfo::nonExistingFileDates()
+void tst_QFileInfo::nonExistingFile()
{
- QFileInfo info("non-existing-file.foobar");
- QVERIFY(!info.exists());
- QVERIFY(!info.created().isValid());
- QVERIFY(!info.lastRead().isValid());
- QVERIFY(!info.lastModified().isValid());
+ QString dirname = QDir::currentPath();
+ QString cdirname = QFileInfo(dirname).canonicalFilePath();
+ if (dirname != cdirname)
+ QDir::setCurrent(cdirname); // chdir() to our canonical path
+
+ QString filename = "non-existing-file-foobar";
+ QFileInfo info(filename);
+ stateCheck(info, dirname, filename);
}
QTEST_MAIN(tst_QFileInfo)
diff --git a/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp b/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp
index 1c104688a5..ea4da39cd5 100644
--- a/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp
+++ b/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp
@@ -66,14 +66,16 @@ void tst_QFileSystemMetaData::timeSinceEpoch()
/* data.ftLastAccessTime = data.ftLastWriteTime = */
data.ftCreationTime = epochToFileTime(afterEpochUtc);
meta.fillFromFindData(data);
+ QCOMPARE(meta.birthTime().toUTC(),
+ QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), Qt::UTC));
#else
QT_STATBUF data;
memset(&data, 0, sizeof(data));
data.st_ctime = afterEpochUtc;
meta.fillFromStatBuf(data);
-#endif
- QCOMPARE(meta.creationTime().toUTC(),
+ QCOMPARE(meta.metadataChangeTime().toUTC(),
QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), Qt::UTC));
+#endif
}
#else // i.e. no Q_AUTOTEST_EXPORT
void tst_QFileSystemMetaData::timeSinceEpoch()
diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
index a76fd4703e..a0188f8ba9 100644
--- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
@@ -55,6 +55,10 @@ private slots:
void readAllKeepPosition();
void writeInTextMode();
+ void skip_data();
+ void skip();
+ void skipAfterPeek_data();
+ void skipAfterPeek();
void transaction_data();
void transaction();
@@ -628,6 +632,93 @@ void tst_QIODevice::writeInTextMode()
#endif
}
+void tst_QIODevice::skip_data()
+{
+ QTest::addColumn<bool>("sequential");
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("read");
+ QTest::addColumn<int>("skip");
+ QTest::addColumn<int>("skipped");
+ QTest::addColumn<char>("expect");
+
+ QByteArray bigData;
+ bigData.fill('a', 20000);
+ bigData[10001] = 'x';
+
+ bool sequential = true;
+ do {
+ QByteArray devName(sequential ? "sequential" : "random-access");
+
+ QTest::newRow(qPrintable(devName + "-small_data")) << true << QByteArray("abcdefghij")
+ << 3 << 6 << 6 << 'j';
+ QTest::newRow(qPrintable(devName + "-big_data")) << true << bigData
+ << 1 << 10000 << 10000 << 'x';
+ QTest::newRow(qPrintable(devName + "-beyond_the_end")) << true << bigData
+ << 1 << 20000 << 19999 << '\0';
+
+ sequential = !sequential;
+ } while (!sequential);
+}
+
+void tst_QIODevice::skip()
+{
+ QFETCH(bool, sequential);
+ QFETCH(QByteArray, data);
+ QFETCH(int, read);
+ QFETCH(int, skip);
+ QFETCH(int, skipped);
+ QFETCH(char, expect);
+ char lastChar = 0;
+
+ QScopedPointer<QIODevice> dev(sequential ? (QIODevice *) new SequentialReadBuffer(&data)
+ : (QIODevice *) new QBuffer(&data));
+ dev->open(QIODevice::ReadOnly);
+
+ for (int i = 0; i < read; ++i)
+ dev->getChar(nullptr);
+
+ QCOMPARE(dev->skip(skip), skipped);
+ dev->getChar(&lastChar);
+ QCOMPARE(lastChar, expect);
+}
+
+void tst_QIODevice::skipAfterPeek_data()
+{
+ QTest::addColumn<bool>("sequential");
+ QTest::addColumn<QByteArray>("data");
+
+ QByteArray bigData;
+ for (int i = 0; i < 1000; ++i)
+ bigData += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ QTest::newRow("sequential") << true << bigData;
+ QTest::newRow("random-access") << false << bigData;
+}
+
+void tst_QIODevice::skipAfterPeek()
+{
+ QFETCH(bool, sequential);
+ QFETCH(QByteArray, data);
+
+ QScopedPointer<QIODevice> dev(sequential ? (QIODevice *) new SequentialReadBuffer(&data)
+ : (QIODevice *) new QBuffer(&data));
+ int readSoFar = 0;
+ qint64 bytesToSkip = 1;
+
+ dev->open(QIODevice::ReadOnly);
+ forever {
+ QByteArray chunk = dev->peek(bytesToSkip);
+ if (chunk.isEmpty())
+ break;
+
+ QCOMPARE(dev->skip(bytesToSkip), qint64(chunk.size()));
+ QCOMPARE(chunk, data.mid(readSoFar, chunk.size()));
+ readSoFar += chunk.size();
+ bytesToSkip <<= 1;
+ }
+ QCOMPARE(readSoFar, data.size());
+}
+
void tst_QIODevice::transaction_data()
{
QTest::addColumn<bool>("sequential");
diff --git a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp
index f10c2a7c98..e086bf1904 100644
--- a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp
+++ b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp
@@ -31,6 +31,12 @@
#include <QLockFile>
#include <QThread>
+#ifdef Q_OS_UNIX
+# include <unistd.h>
+#else
+# include <stdlib.h>
+#endif
+
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
@@ -44,11 +50,11 @@ int main(int argc, char *argv[])
if (argc > 2)
option = QString::fromLocal8Bit(argv[2]);
- if (option == "-crash") {
+ if (option == "-uncleanexit") {
QLockFile lockFile(lockName);
lockFile.lock();
// exit on purpose, so that the lock remains!
- exit(0);
+ _exit(0);
} else if (option == "-busy") {
QLockFile lockFile(lockName);
lockFile.lock();
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
index d2f345feb5..835c4a2778 100644
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
@@ -262,7 +262,7 @@ void tst_QLockFile::staleLockFromCrashedProcess()
QFETCH(int, staleLockTime);
const QString fileName = dir.path() + "/staleLockFromCrashedProcess";
- int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-crash");
+ int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-uncleanexit");
QCOMPARE(ret, int(QLockFile::NoError));
QTRY_VERIFY(QFile::exists(fileName));
@@ -288,7 +288,7 @@ void tst_QLockFile::staleLockFromCrashedProcessReusedPid()
#else
const QString fileName = dir.path() + "/staleLockFromCrashedProcessReusedPid";
- int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-crash");
+ int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-uncleanexit");
QCOMPARE(ret, int(QLockFile::NoError));
QVERIFY(QFile::exists(fileName));
QVERIFY(overwritePidInLockFile(fileName, QCoreApplication::applicationPid()));
@@ -397,7 +397,7 @@ void tst_QLockFile::staleLockRace()
// Only one thread should delete it, otherwise a race will ensue
const QString fileName = dir.path() + "/sharedFile";
const QString lockName = fileName + ".lock";
- int ret = QProcess::execute(m_helperApp, QStringList() << lockName << "-crash");
+ int ret = QProcess::execute(m_helperApp, QStringList() << lockName << "-uncleanexit");
QCOMPARE(ret, int(QLockFile::NoError));
QTRY_VERIFY(QFile::exists(lockName));
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/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index 9573f3078b..96970421d3 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -82,6 +82,11 @@ private slots:
void transactionalWriteErrorRenaming();
void symlink();
void directory();
+
+#ifdef Q_OS_WIN
+ void alternateDataStream_data();
+ void alternateDataStream();
+#endif
};
static inline QByteArray msgCannotOpen(const QFileDevice &f)
@@ -474,5 +479,60 @@ void tst_QSaveFile::directory()
#endif
}
+#ifdef Q_OS_WIN
+void tst_QSaveFile::alternateDataStream_data()
+{
+ QTest::addColumn<bool>("directWriteFallback");
+ QTest::addColumn<bool>("success");
+
+ QTest::newRow("default") << false << false;
+ QTest::newRow("directWriteFallback") << true << true;
+}
+
+void tst_QSaveFile::alternateDataStream()
+{
+ QFETCH(bool, directWriteFallback);
+ QFETCH(bool, success);
+ static const char newContent[] = "New content\r\n";
+
+ QTemporaryDir dir;
+ QVERIFY2(dir.isValid(), qPrintable(dir.errorString()));
+ QString baseName = dir.path() + QLatin1String("/base");
+ {
+ QFile baseFile(baseName);
+ QVERIFY2(baseFile.open(QIODevice::ReadWrite), qPrintable(baseFile.errorString()));
+ }
+
+ // First, create a file with old content
+ QString adsName = baseName + QLatin1String(":outfile");
+ {
+ QFile targetFile(adsName);
+ if (!targetFile.open(QIODevice::ReadWrite))
+ QSKIP("Failed to ceate ADS file (" + targetFile.errorString().toUtf8()
+ + "). Temp dir is FAT?");
+ targetFile.write("Old content\r\n");
+ }
+
+ // And write to it again using QSaveFile; only works if directWriteFallback is enabled
+ QSaveFile file(adsName);
+ file.setDirectWriteFallback(directWriteFallback);
+ QCOMPARE(file.directWriteFallback(), directWriteFallback);
+
+ if (success) {
+ QVERIFY2(file.open(QIODevice::WriteOnly), qPrintable(file.errorString()));
+ file.write(newContent);
+ QVERIFY2(file.commit(), qPrintable(file.errorString()));
+
+ // check the contents
+ QFile targetFile(adsName);
+ QVERIFY2(targetFile.open(QIODevice::ReadOnly), qPrintable(targetFile.errorString()));
+ QByteArray contents = targetFile.readAll();
+ QCOMPARE(contents, QByteArray(newContent));
+ } else {
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+ }
+}
+#endif
+
QTEST_MAIN(tst_QSaveFile)
#include "tst_qsavefile.moc"
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index 332c2dcc01..012ce5f2f5 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -118,6 +118,10 @@ private slots:
void remove();
void contains();
void sync();
+ void syncNonWriteableDir();
+#ifdef Q_OS_WIN
+ void syncAlternateDataStream();
+#endif
void setFallbacksEnabled();
void setFallbacksEnabled_data();
void fromFile_data();
@@ -1750,6 +1754,78 @@ void tst_QSettings::sync()
QCOMPARE(settings1.allKeys().count(), 11);
}
+void tst_QSettings::syncNonWriteableDir()
+{
+ QTemporaryDir tempDir;
+ QVERIFY2(tempDir.isValid(), qUtf8Printable(tempDir.errorString()));
+
+ // first, create a file
+ QString filename = tempDir.path() + "/config.ini";
+ {
+ QFile f(filename);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qUtf8Printable(f.errorString()));
+ }
+
+ // second, make the dir unwriteable
+ QVERIFY(QFile::setPermissions(tempDir.path(), QFile::ReadUser | QFile::ExeUser));
+ struct UndoSetPermissions {
+ QString name;
+ UndoSetPermissions(const QString &name) : name(name) {}
+ ~UndoSetPermissions()
+ { QFile::setPermissions(name, QFile::ReadUser | QFile::WriteUser | QFile::ExeUser); }
+ };
+ UndoSetPermissions undo(tempDir.path()); // otherwise, QTemporaryDir will fail
+
+ {
+ QSettings settings(filename, QSettings::IniFormat);
+ QVERIFY(settings.isAtomicSyncRequired());
+ settings.setAtomicSyncRequired(false);
+ settings.setValue("alpha/beta", 1);
+ settings.sync();
+ QCOMPARE(settings.status(), QSettings::NoError);
+ }
+
+ QVERIFY(QFileInfo(filename).size() != 0);
+ QSettings settings(filename, QSettings::IniFormat);
+ QCOMPARE(settings.value("alpha/beta"), QVariant(1));
+}
+
+#ifdef Q_OS_WIN
+void tst_QSettings::syncAlternateDataStream()
+{
+ QTemporaryDir tempDir;
+ QVERIFY2(tempDir.isValid(), qUtf8Printable(tempDir.errorString()));
+
+ // first, create a file
+ QString filename = tempDir.path() + "/file";
+ {
+ QFile f(filename);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qUtf8Printable(f.errorString()));
+ }
+
+ // then create an ADS
+ filename += ":config.ini";
+ {
+ QFile f(filename);
+ if (!f.open(QIODevice::WriteOnly))
+ QSKIP("Could not create ADS file (" + f.errorString().toUtf8() + ") - FAT drive?");
+ }
+
+ {
+ QSettings settings(filename, QSettings::IniFormat);
+ QVERIFY(settings.isAtomicSyncRequired());
+ settings.setAtomicSyncRequired(false);
+ settings.setValue("alpha/beta", 1);
+ settings.sync();
+ QCOMPARE(settings.status(), QSettings::NoError);
+ }
+
+ QVERIFY(QFileInfo(filename).size() != 0);
+ QSettings settings(filename, QSettings::IniFormat);
+ QCOMPARE(settings.value("alpha/beta"), QVariant(1));
+}
+#endif
+
void tst_QSettings::setFallbacksEnabled_data()
{
populateWithFormats();
diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
index 4cb3bfe549..76462be376 100644
--- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -139,25 +139,24 @@ void tst_QTemporaryDir::fileTemplate_data()
{
QTest::addColumn<QString>("constructorTemplate");
QTest::addColumn<QString>("prefix");
+ QTest::addColumn<QString>("suffix");
+
+ QTest::newRow("default") << "" << "tst_qtemporarydir-" << "";
- QTest::newRow("constructor default") << "" << "tst_qtemporarydir-";
-
- QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_XXXXXXxxx";
- QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_XXXXXXxXx";
- QTest::newRow("constructor with no suffix") << "qt_XXXXXX" << "qt_";
- QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_";
- // When more than 6 X are present at the end, linux and windows will only replace the last 6,
- // while Mac OS will actually replace all of them so we can only expect "qt_" (and check isValid).
- QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_";
- QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_";
- QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_";
+ QTest::newRow("xxx-suffix") << "qt_XXXXXXxxx" << "qt_" << "xxx";
+ QTest::newRow("xXx-suffix") << "qt_XXXXXXxXx" << "qt_" << "xXx";
+ QTest::newRow("no-suffix") << "qt_XXXXXX" << "qt_" << "";
+ QTest::newRow("10X") << "qt_XXXXXXXXXX" << "qt_" << "";
+ QTest::newRow("4Xsuffix") << "qt_XXXXXX_XXXX" << "qt_" << "_XXXX";
+ QTest::newRow("4Xprefix") << "qt_XXXX" << "qt_XXXX" << "";
+ QTest::newRow("5Xprefix") << "qt_XXXXX" << "qt_XXXXX" << "";
if (QTestPrivate::canHandleUnicodeFileNames()) {
// Test Umlauts (contained in Latin1)
QString prefix = "qt_" + umlautTestText();
- QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix;
- // Test Chinese
+ QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix << "";
+ // test non-Latin1
prefix = "qt_" + hanTestText();
- QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix;
+ QTest::newRow("Chinese") << (prefix + "XXXXXX" + umlautTestText()) << prefix << umlautTestText();
}
}
@@ -165,14 +164,17 @@ void tst_QTemporaryDir::fileTemplate()
{
QFETCH(QString, constructorTemplate);
QFETCH(QString, prefix);
+ QFETCH(QString, suffix);
QTemporaryDir tempDir(constructorTemplate);
QVERIFY(tempDir.isValid());
QString dirName = QDir(tempDir.path()).dirName();
- if (prefix.length())
+ if (prefix.length()) {
QCOMPARE(dirName.left(prefix.length()), prefix);
+ QCOMPARE(dirName.right(suffix.length()), suffix);
+ }
}
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index 64b61839c1..f3ce902bbd 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -32,6 +33,7 @@
#include <qtemporarydir.h>
#include <qtemporaryfile.h>
#include <qfile.h>
+#include <qdatetime.h>
#include <qdir.h>
#include <qset.h>
#include <qtextcodec.h>
@@ -65,7 +67,7 @@ private slots:
void fileNameIsEmpty();
void autoRemove();
void nonWritableCurrentDir();
- void write();
+ void io();
void openCloseOpenClose();
void removeAndReOpen();
void size();
@@ -278,6 +280,18 @@ void tst_QTemporaryFile::autoRemove()
fileName = file.fileName();
file.close();
}
+ QVERIFY(!fileName.isEmpty());
+ QVERIFY(!QFile::exists(fileName));
+
+ // same, but gets the file name after closing
+ {
+ QTemporaryFile file("tempXXXXXX");
+ file.setAutoRemove(true);
+ QVERIFY(file.open());
+ file.close();
+ fileName = file.fileName();
+ }
+ QVERIFY(!fileName.isEmpty());
QVERIFY(!QFile::exists(fileName));
// Test if disabling auto remove works.
@@ -288,6 +302,19 @@ void tst_QTemporaryFile::autoRemove()
fileName = file.fileName();
file.close();
}
+ QVERIFY(!fileName.isEmpty());
+ QVERIFY(QFile::exists(fileName));
+ QVERIFY(QFile::remove(fileName));
+
+ // same, but gets the file name after closing
+ {
+ QTemporaryFile file("tempXXXXXX");
+ file.setAutoRemove(false);
+ QVERIFY(file.open());
+ file.close();
+ fileName = file.fileName();
+ }
+ QVERIFY(!fileName.isEmpty());
QVERIFY(QFile::exists(fileName));
QVERIFY(QFile::remove(fileName));
@@ -338,17 +365,51 @@ void tst_QTemporaryFile::nonWritableCurrentDir()
#endif
}
-void tst_QTemporaryFile::write()
+void tst_QTemporaryFile::io()
{
QByteArray data("OLE\nOLE\nOLE");
QTemporaryFile file;
+ QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-250);
+
+ // discard msec component (round down) - not all FSs and OSs support them
+ before.setSecsSinceEpoch(before.toSecsSinceEpoch());
+
QVERIFY(file.open());
+ QVERIFY(file.readLink().isEmpty()); // it's not a link!
+ QFile::Permissions perm = file.permissions();
+ QVERIFY(perm & QFile::ReadOwner);
+ QVERIFY(file.setPermissions(perm));
+
+ QCOMPARE(int(file.size()), 0);
+ QVERIFY(file.resize(data.size()));
+ QCOMPARE(int(file.size()), data.size());
QCOMPARE((int)file.write(data), data.size());
+ QCOMPARE(int(file.size()), data.size());
+
+ QDateTime mtime = file.fileTime(QFile::FileModificationTime).toUTC();
+ QDateTime btime = file.fileTime(QFile::FileBirthTime).toUTC();
+ QDateTime ctime = file.fileTime(QFile::FileMetadataChangeTime).toUTC();
+ QDateTime atime = file.fileTime(QFile::FileAccessTime).toUTC();
+
+ QDateTime after = QDateTime::currentDateTimeUtc().toUTC().addMSecs(250);
+ // round msecs up
+ after.setSecsSinceEpoch(after.toSecsSinceEpoch() + 1);
+
+ // mtime must be valid, the rest could fail
+ QVERIFY(mtime <= after && mtime >= before);
+ QVERIFY(!btime.isValid() || (btime <= after && btime >= before));
+ QVERIFY(!ctime.isValid() || (ctime <= after && ctime >= before));
+ QVERIFY(!btime.isValid() || (btime <= after && btime >= before));
+
+ QVERIFY(file.setFileTime(before.addSecs(-10), QFile::FileModificationTime));
+ mtime = file.fileTime(QFile::FileModificationTime).toUTC();
+ QCOMPARE(mtime, before.addSecs(-10));
+
file.reset();
QFile compare(file.fileName());
compare.open(QIODevice::ReadOnly);
QCOMPARE(compare.readAll() , data);
- file.close();
+ QCOMPARE(compare.fileTime(QFile::FileModificationTime), mtime);
}
void tst_QTemporaryFile::openCloseOpenClose()
@@ -399,17 +460,19 @@ void tst_QTemporaryFile::size()
{
QTemporaryFile file;
QVERIFY(file.open());
- QVERIFY(file.exists());
QVERIFY(!file.isSequential());
QByteArray str("foobar");
file.write(str);
- QVERIFY(QFile::exists(file.fileName()));
+
// On CE it takes more time for the filesystem to update
// the information. Usually you have to close it or seek
// to get latest information. flush() does not help either.
QCOMPARE(file.size(), qint64(6));
file.seek(0);
QCOMPARE(file.size(), qint64(6));
+
+ QVERIFY(QFile::exists(file.fileName()));
+ QVERIFY(file.exists());
}
void tst_QTemporaryFile::resize()
@@ -806,6 +869,14 @@ void tst_QTemporaryFile::QTBUG_4796()
QCOMPARE(file5.open(), openResult);
QCOMPARE(file6.open(), openResult);
+ // force the files to exist, if they are supposed to
+ QCOMPARE(!file1.fileName().isEmpty(), openResult);
+ QCOMPARE(!file2.fileName().isEmpty(), openResult);
+ QCOMPARE(!file3.fileName().isEmpty(), openResult);
+ QCOMPARE(!file4.fileName().isEmpty(), openResult);
+ QCOMPARE(!file5.fileName().isEmpty(), openResult);
+ QCOMPARE(!file6.fileName().isEmpty(), openResult);
+
QCOMPARE(file1.exists(), openResult);
QCOMPARE(file2.exists(), openResult);
QCOMPARE(file3.exists(), openResult);
@@ -861,8 +932,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();
@@ -876,8 +945,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 0bbd1b9f15..20282068cb 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"