summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io/qtemporarydir
diff options
context:
space:
mode:
authorDavid Faure <faure@kde.org>2011-11-30 18:00:12 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-02 21:04:34 +0100
commite999c543a052a3301319329f78a8080c3df0669c (patch)
tree61f78ad131bfd32c85f639396f1bada36446c03b /tests/auto/corelib/io/qtemporarydir
parent4d696d53b074dafc1ecfc1d9cb6fd041464e1a75 (diff)
New class QTemporaryDir.
As discussed on qt5-feedback / development lists. Change-Id: If1733369d12daa29054776ec2cbd78e63679768e Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Diffstat (limited to 'tests/auto/corelib/io/qtemporarydir')
-rw-r--r--tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro7
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp471
2 files changed, 478 insertions, 0 deletions
diff --git a/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro b/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro
new file mode 100644
index 0000000000..b34d2cca07
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase
+TARGET = tst_qtemporarydir
+SOURCES += tst_qtemporarydir.cpp
+
+QT = core testlib
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
new file mode 100644
index 0000000000..e1ead8c9c0
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -0,0 +1,471 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <qcoreapplication.h>
+#include <qstring.h>
+#include <qtemporarydir.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qset.h>
+#ifdef Q_OS_WIN
+# include <windows.h>
+#endif
+
+//TESTED_CLASS=QTemporaryDir
+//TESTED_FILES=qtemporarydir.cpp
+
+class tst_QTemporaryDir : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QTemporaryDir();
+ virtual ~tst_QTemporaryDir();
+public slots:
+ void init();
+ void cleanup();
+
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void construction();
+ void fileTemplate();
+ void fileTemplate_data();
+ void getSetCheck();
+ void fileName();
+ void autoRemove();
+ void nonWritableCurrentDir();
+ void openOnRootDrives();
+ void stressTest();
+ void rename();
+ void autoRemoveAfterFailedRename();
+
+ void QTBUG_4796_data();
+ void QTBUG_4796();
+
+public:
+};
+
+void tst_QTemporaryDir::initTestCase()
+{
+ QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX"));
+ QCoreApplication::setApplicationName("tst_qtemporarydir");
+}
+
+void tst_QTemporaryDir::cleanupTestCase()
+{
+ QVERIFY(QDir().rmdir("test-XXXXXX"));
+}
+
+void tst_QTemporaryDir::construction()
+{
+ QTemporaryDir dir;
+ QString tmp = QDir::tempPath();
+ QCOMPARE(dir.path().left(tmp.size()), tmp);
+ QVERIFY(dir.path().contains("tst_qtemporarydir"));
+ QVERIFY(QFileInfo(dir.path()).isDir());
+}
+
+// Testing get/set functions
+void tst_QTemporaryDir::getSetCheck()
+{
+ QTemporaryDir obj1;
+ // bool QTemporaryDir::autoRemove()
+ // void QTemporaryDir::setAutoRemove(bool)
+ obj1.setAutoRemove(false);
+ QCOMPARE(false, obj1.autoRemove());
+ obj1.setAutoRemove(true);
+ QCOMPARE(true, obj1.autoRemove());
+}
+
+tst_QTemporaryDir::tst_QTemporaryDir()
+{
+}
+
+tst_QTemporaryDir::~tst_QTemporaryDir()
+{
+
+}
+
+void tst_QTemporaryDir::init()
+{
+}
+
+void tst_QTemporaryDir::cleanup()
+{
+}
+
+void tst_QTemporaryDir::fileTemplate_data()
+{
+ QTest::addColumn<QString>("constructorTemplate");
+ QTest::addColumn<QString>("prefix");
+
+ 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_XXXX";
+ QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_";
+ QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_XXXX";
+ QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_XXXXX";
+}
+
+void tst_QTemporaryDir::fileTemplate()
+{
+ QFETCH(QString, constructorTemplate);
+ QFETCH(QString, prefix);
+
+ QTemporaryDir tempDir(constructorTemplate);
+
+ QVERIFY(tempDir.isValid());
+
+ QString dirName = QDir(tempDir.path()).dirName();
+ if (prefix.length())
+ QCOMPARE(dirName.left(prefix.length()), prefix);
+}
+
+
+/*
+ This tests whether the temporary dir really gets placed in QDir::tempPath
+*/
+void tst_QTemporaryDir::fileName()
+{
+ // Get QDir::tempPath and make an absolute path.
+ QString tempPath = QDir::tempPath();
+ QString absoluteTempPath = QDir(tempPath).absolutePath();
+ QTemporaryDir dir;
+ dir.setAutoRemove(true);
+ QString fileName = dir.path();
+ QVERIFY2(fileName.contains("/tst_qtemporarydir-"), qPrintable(fileName));
+ QVERIFY(QFile::exists(fileName));
+ // Get path to the temp dir, without the file name.
+ QString absoluteFilePath = QFileInfo(fileName).absolutePath();
+#if defined(Q_OS_WIN)
+ absoluteFilePath = absoluteFilePath.toLower();
+ absoluteTempPath = absoluteTempPath.toLower();
+#endif
+ QCOMPARE(absoluteFilePath, absoluteTempPath);
+}
+
+void tst_QTemporaryDir::autoRemove()
+{
+ // Test auto remove
+ QString dirName;
+ {
+ QTemporaryDir dir("tempXXXXXX");
+ dir.setAutoRemove(true);
+ QVERIFY(dir.isValid());
+ dirName = dir.path();
+ }
+#ifdef Q_OS_WIN
+ // Windows seems unreliable here: sometimes it says the directory still exists,
+ // immediately after we deleted it.
+ QTRY_VERIFY(!QFile::exists(dirName));
+#else
+ QVERIFY(!QFile::exists(dirName));
+#endif
+
+ // Test if disabling auto remove works.
+ {
+ QTemporaryDir dir("tempXXXXXX");
+ dir.setAutoRemove(false);
+ QVERIFY(dir.isValid());
+ dirName = dir.path();
+ }
+ QVERIFY(QFile::exists(dirName));
+ QVERIFY(QDir().rmdir(dirName));
+ QVERIFY(!QFile::exists(dirName));
+
+ // Do not explicitly call setAutoRemove (tests if it really is the default as documented)
+ {
+ QTemporaryDir dir("tempXXXXXX");
+ QVERIFY(dir.isValid());
+ dirName = dir.path();
+ }
+#ifdef Q_OS_WIN
+ QTRY_VERIFY(!QFile::exists(dirName));
+#else
+ QVERIFY(!QFile::exists(dirName));
+#endif
+
+ // Test autoremove with files and subdirs in the temp dir
+ {
+ QTemporaryDir tempDir("tempXXXXXX");
+ QVERIFY(tempDir.isValid());
+ dirName = tempDir.path();
+ QDir dir(dirName);
+ QVERIFY(dir.mkdir(QString::fromLatin1("dir1")));
+ QVERIFY(dir.mkdir(QString::fromLatin1("dir2")));
+ QVERIFY(dir.mkdir(QString::fromLatin1("dir2/nested")));
+ QFile file(dirName + "/dir1/file");
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE(file.write("Hello"), 5LL);
+ }
+#ifdef Q_OS_WIN
+ QTRY_VERIFY(!QFile::exists(dirName));
+#else
+ QVERIFY(!QFile::exists(dirName));
+#endif
+}
+
+void tst_QTemporaryDir::nonWritableCurrentDir()
+{
+#ifdef Q_OS_UNIX
+ QString cwd = QDir::currentPath();
+ QDir::setCurrent("/");
+ // QTemporaryDir("tempXXXXXX") is probably a bad idea in any app
+ // where the current dir could anything...
+ QString fileName;
+ QTemporaryDir dir("tempXXXXXX");
+ dir.setAutoRemove(true);
+ QVERIFY(!dir.isValid());
+ fileName = dir.path();
+ QDir::setCurrent(cwd);
+#endif
+}
+
+void tst_QTemporaryDir::openOnRootDrives()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+ // If it's possible to create a dir in the root directory, it
+ // must be possible to create a temp dir there too.
+ foreach (const QFileInfo &driveInfo, QDir::drives()) {
+ QFile testFile(driveInfo.filePath() + "XXXXXX.txt");
+ if (testFile.open(QIODevice::ReadWrite)) {
+ testFile.remove();
+ QTemporaryDir dir(driveInfo.filePath() + "XXXXXX.txt");
+ dir.setAutoRemove(true);
+ QVERIFY(dir.isValid());
+ }
+ }
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ SetErrorMode(lastErrorMode);
+#endif
+}
+
+void tst_QTemporaryDir::stressTest()
+{
+ const int iterations = 1000;
+
+ QSet<QString> names;
+ for (int i = 0; i < iterations; ++i) {
+ QTemporaryDir dir;
+ dir.setAutoRemove(false);
+ QVERIFY2(dir.isValid(), qPrintable(QString::number(i)));
+ QVERIFY(!names.contains(dir.path()));
+ names.insert(dir.path());
+ }
+ for (QSet<QString>::const_iterator it = names.constBegin(); it != names.constEnd(); ++it)
+ QDir(*it).removeRecursively();
+}
+
+void tst_QTemporaryDir::rename()
+{
+ // This test checks what happens if the temporary dir is renamed.
+ // Then the autodelete feature can't possibly find it.
+
+ QDir dir;
+ QVERIFY(!dir.exists("temporary-dir.renamed"));
+
+ QString tempname;
+ {
+ QTemporaryDir tempDir(dir.filePath("temporary-dir.XXXXXX"));
+
+ QVERIFY(tempDir.isValid());
+ tempname = tempDir.path();
+
+ QVERIFY(QDir().rename(tempname, "temporary-dir.renamed"));
+ QVERIFY(!QDir(tempname).exists());
+ dir.setPath("temporary-dir.renamed");
+ QCOMPARE(dir.path(), QString("temporary-dir.renamed"));
+ QVERIFY(dir.exists());
+ }
+
+ // Auto-delete couldn't find it
+ QVERIFY(dir.exists());
+ // Clean up by hand
+ QVERIFY(dir.removeRecursively());
+ QVERIFY(!dir.exists());
+}
+
+void tst_QTemporaryDir::autoRemoveAfterFailedRename()
+{
+ struct CleanOnReturn
+ {
+ ~CleanOnReturn()
+ {
+ if (!tempName.isEmpty())
+ QVERIFY(QDir(tempName).removeRecursively());
+ }
+
+ void reset()
+ {
+ tempName.clear();
+ }
+
+ QString tempName;
+ };
+
+ CleanOnReturn cleaner;
+
+ {
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+ cleaner.tempName = dir.path();
+
+ QVERIFY(QFile::exists(cleaner.tempName));
+ QVERIFY(!QFileInfo("i-do-not-exist").isDir());
+ QVERIFY(!QDir().rename(cleaner.tempName, "i-do-not-exist/dir.txt"));
+ QVERIFY(QFile::exists(cleaner.tempName));
+ }
+
+ QVERIFY(!QFile::exists(cleaner.tempName));
+ cleaner.reset();
+}
+
+void tst_QTemporaryDir::QTBUG_4796_data()
+{
+ QTest::addColumn<QString>("prefix");
+ QTest::addColumn<QString>("suffix");
+ QTest::addColumn<bool>("openResult");
+
+ QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
+
+ QTest::newRow("<empty>") << QString() << QString() << true;
+ QTest::newRow(".") << QString(".") << QString() << true;
+ QTest::newRow("..") << QString("..") << QString() << true;
+ QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
+ QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
+ QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true;
+ QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
+}
+
+void tst_QTemporaryDir::QTBUG_4796()
+{
+ QVERIFY(QDir("test-XXXXXX").exists());
+
+ struct CleanOnReturn
+ {
+ ~CleanOnReturn()
+ {
+ foreach (const QString &tempName, tempNames)
+ QVERIFY(QDir(tempName).removeRecursively());
+ }
+
+ void reset()
+ {
+ tempNames.clear();
+ }
+
+ QStringList tempNames;
+ };
+
+ CleanOnReturn cleaner;
+
+ QFETCH(QString, prefix);
+ QFETCH(QString, suffix);
+ QFETCH(bool, openResult);
+
+ {
+ QString fileTemplate1 = prefix + QString("XX") + suffix;
+ QString fileTemplate2 = prefix + QString("XXXX") + suffix;
+ QString fileTemplate3 = prefix + QString("XXXXXX") + suffix;
+ QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix;
+
+ QTemporaryDir dir1(fileTemplate1);
+ QTemporaryDir dir2(fileTemplate2);
+ QTemporaryDir dir3(fileTemplate3);
+ QTemporaryDir dir4(fileTemplate4);
+ QTemporaryDir dir5("test-XXXXXX/" + fileTemplate1);
+ QTemporaryDir dir6("test-XXXXXX/" + fileTemplate3);
+
+ QCOMPARE(dir1.isValid(), openResult);
+ QCOMPARE(dir2.isValid(), openResult);
+ QCOMPARE(dir3.isValid(), openResult);
+ QCOMPARE(dir4.isValid(), openResult);
+ QCOMPARE(dir5.isValid(), openResult);
+ QCOMPARE(dir6.isValid(), openResult);
+
+ // make sure the dir exists under the *correct* name
+ if (openResult) {
+ cleaner.tempNames << dir1.path()
+ << dir2.path()
+ << dir3.path()
+ << dir4.path()
+ << dir5.path()
+ << dir6.path();
+
+ QDir currentDir;
+ QString fileName1 = currentDir.relativeFilePath(dir1.path());
+ QString fileName2 = currentDir.relativeFilePath(dir2.path());
+ QString fileName3 = currentDir.relativeFilePath(dir3.path());
+ QString fileName4 = currentDir.relativeFilePath(dir4.path());
+ QString fileName5 = currentDir.relativeFilePath(dir5.path());
+ QString fileName6 = currentDir.relativeFilePath(dir6.path());
+
+ QVERIFY(fileName1.startsWith(fileTemplate1));
+ QVERIFY(fileName2.startsWith(fileTemplate2));
+ QVERIFY(fileName5.startsWith("test-XXXXXX/" + fileTemplate1));
+ QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix));
+
+ if (!prefix.isEmpty()) {
+ QVERIFY(fileName3.startsWith(prefix));
+ QVERIFY(fileName4.startsWith(prefix));
+ }
+ }
+ }
+
+#ifdef Q_OS_WIN
+ QTest::qWait(20);
+#endif
+ foreach (const QString &tempName, cleaner.tempNames)
+ QVERIFY2(!QFile::exists(tempName), qPrintable(tempName));
+
+ cleaner.reset();
+}
+
+QTEST_MAIN(tst_QTemporaryDir)
+#include "tst_qtemporarydir.moc"