~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
 
 
43
#include <QtTest/QtTest>
 
44
#include <qcoreapplication.h>
 
45
#include <qstring.h>
 
46
#include <qtemporarydir.h>
 
47
#include <qfile.h>
 
48
#include <qdir.h>
 
49
#include <qset.h>
 
50
#ifdef Q_OS_WIN
 
51
# include <windows.h>
 
52
#endif
 
53
#ifdef Q_OS_UNIX // for geteuid()
 
54
# include <sys/types.h>
 
55
# include <unistd.h>
 
56
#endif
 
57
 
 
58
class tst_QTemporaryDir : public QObject
 
59
{
 
60
    Q_OBJECT
 
61
public:
 
62
public slots:
 
63
    void initTestCase();
 
64
    void cleanupTestCase();
 
65
 
 
66
private slots:
 
67
    void construction();
 
68
    void fileTemplate();
 
69
    void fileTemplate_data();
 
70
    void getSetCheck();
 
71
    void fileName();
 
72
    void autoRemove();
 
73
    void nonWritableCurrentDir();
 
74
    void openOnRootDrives();
 
75
    void stressTest();
 
76
    void rename();
 
77
 
 
78
    void QTBUG_4796_data();
 
79
    void QTBUG_4796();
 
80
 
 
81
public:
 
82
};
 
83
 
 
84
void tst_QTemporaryDir::initTestCase()
 
85
{
 
86
    QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX"));
 
87
    QCoreApplication::setApplicationName("tst_qtemporarydir");
 
88
}
 
89
 
 
90
void tst_QTemporaryDir::cleanupTestCase()
 
91
{
 
92
    QVERIFY(QDir().rmdir("test-XXXXXX"));
 
93
}
 
94
 
 
95
void tst_QTemporaryDir::construction()
 
96
{
 
97
    QTemporaryDir dir;
 
98
    QString tmp = QDir::tempPath();
 
99
    QCOMPARE(dir.path().left(tmp.size()), tmp);
 
100
    QVERIFY(dir.path().contains("tst_qtemporarydir"));
 
101
    QVERIFY(QFileInfo(dir.path()).isDir());
 
102
}
 
103
 
 
104
// Testing get/set functions
 
105
void tst_QTemporaryDir::getSetCheck()
 
106
{
 
107
    QTemporaryDir obj1;
 
108
    // bool QTemporaryDir::autoRemove()
 
109
    // void QTemporaryDir::setAutoRemove(bool)
 
110
    obj1.setAutoRemove(false);
 
111
    QCOMPARE(false, obj1.autoRemove());
 
112
    obj1.setAutoRemove(true);
 
113
    QCOMPARE(true, obj1.autoRemove());
 
114
}
 
115
 
 
116
void tst_QTemporaryDir::fileTemplate_data()
 
117
{
 
118
    QTest::addColumn<QString>("constructorTemplate");
 
119
    QTest::addColumn<QString>("prefix");
 
120
 
 
121
    QTest::newRow("constructor default") << "" << "tst_qtemporarydir-";
 
122
 
 
123
    QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_XXXXXXxxx";
 
124
    QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_XXXXXXxXx";
 
125
    QTest::newRow("constructor with no suffix") << "qt_XXXXXX" << "qt_";
 
126
    QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_";
 
127
    // When more than 6 X are present at the end, linux and windows will only replace the last 6,
 
128
    // while Mac OS will actually replace all of them so we can only expect "qt_" (and check isValid).
 
129
    QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_";
 
130
    QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_";
 
131
    QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_";
 
132
}
 
133
 
 
134
void tst_QTemporaryDir::fileTemplate()
 
135
{
 
136
    QFETCH(QString, constructorTemplate);
 
137
    QFETCH(QString, prefix);
 
138
 
 
139
    QTemporaryDir tempDir(constructorTemplate);
 
140
 
 
141
    QVERIFY(tempDir.isValid());
 
142
 
 
143
    QString dirName = QDir(tempDir.path()).dirName();
 
144
    if (prefix.length())
 
145
        QCOMPARE(dirName.left(prefix.length()), prefix);
 
146
}
 
147
 
 
148
 
 
149
/*
 
150
    This tests whether the temporary dir really gets placed in QDir::tempPath
 
151
*/
 
152
void tst_QTemporaryDir::fileName()
 
153
{
 
154
    // Get QDir::tempPath and make an absolute path.
 
155
    QString tempPath = QDir::tempPath();
 
156
    QString absoluteTempPath = QDir(tempPath).absolutePath();
 
157
    QTemporaryDir dir;
 
158
    dir.setAutoRemove(true);
 
159
    QString fileName = dir.path();
 
160
    QVERIFY2(fileName.contains("/tst_qtemporarydir-"), qPrintable(fileName));
 
161
    QVERIFY(QDir(fileName).exists());
 
162
    // Get path to the temp dir, without the file name.
 
163
    QString absoluteFilePath = QFileInfo(fileName).absolutePath();
 
164
#if defined(Q_OS_WIN)
 
165
    absoluteFilePath = absoluteFilePath.toLower();
 
166
    absoluteTempPath = absoluteTempPath.toLower();
 
167
#endif
 
168
    QCOMPARE(absoluteFilePath, absoluteTempPath);
 
169
}
 
170
 
 
171
void tst_QTemporaryDir::autoRemove()
 
172
{
 
173
    // Test auto remove
 
174
    QString dirName;
 
175
    {
 
176
        QTemporaryDir dir("tempXXXXXX");
 
177
        dir.setAutoRemove(true);
 
178
        QVERIFY(dir.isValid());
 
179
        dirName = dir.path();
 
180
    }
 
181
#ifdef Q_OS_WIN
 
182
    // Windows seems unreliable here: sometimes it says the directory still exists,
 
183
    // immediately after we deleted it.
 
184
    QTRY_VERIFY(!QDir(dirName).exists());
 
185
#else
 
186
    QVERIFY(!QDir(dirName).exists());
 
187
#endif
 
188
 
 
189
    // Test if disabling auto remove works.
 
190
    {
 
191
        QTemporaryDir dir("tempXXXXXX");
 
192
        dir.setAutoRemove(false);
 
193
        QVERIFY(dir.isValid());
 
194
        dirName = dir.path();
 
195
    }
 
196
    QVERIFY(QDir(dirName).exists());
 
197
    QVERIFY(QDir().rmdir(dirName));
 
198
    QVERIFY(!QDir(dirName).exists());
 
199
 
 
200
    // Do not explicitly call setAutoRemove (tests if it really is the default as documented)
 
201
    {
 
202
        QTemporaryDir dir("tempXXXXXX");
 
203
        QVERIFY(dir.isValid());
 
204
        dirName = dir.path();
 
205
    }
 
206
#ifdef Q_OS_WIN
 
207
    QTRY_VERIFY(!QDir(dirName).exists());
 
208
#else
 
209
    QVERIFY(!QDir(dirName).exists());
 
210
#endif
 
211
 
 
212
    // Test autoremove with files and subdirs in the temp dir
 
213
    {
 
214
        QTemporaryDir tempDir("tempXXXXXX");
 
215
        QVERIFY(tempDir.isValid());
 
216
        dirName = tempDir.path();
 
217
        QDir dir(dirName);
 
218
        QVERIFY(dir.mkdir(QString::fromLatin1("dir1")));
 
219
        QVERIFY(dir.mkdir(QString::fromLatin1("dir2")));
 
220
        QVERIFY(dir.mkdir(QString::fromLatin1("dir2/nested")));
 
221
        QFile file(dirName + "/dir1/file");
 
222
        QVERIFY(file.open(QIODevice::WriteOnly));
 
223
        QCOMPARE(file.write("Hello"), 5LL);
 
224
    }
 
225
#ifdef Q_OS_WIN
 
226
    QTRY_VERIFY(!QDir(dirName).exists());
 
227
#else
 
228
    QVERIFY(!QDir(dirName).exists());
 
229
#endif
 
230
}
 
231
 
 
232
void tst_QTemporaryDir::nonWritableCurrentDir()
 
233
{
 
234
#ifdef Q_OS_UNIX
 
235
    if (::geteuid() == 0)
 
236
        QSKIP("not valid running this test as root");
 
237
 
 
238
    struct ChdirOnReturn
 
239
    {
 
240
        ChdirOnReturn(const QString& d) : dir(d) {}
 
241
        ~ChdirOnReturn() {
 
242
            QDir::setCurrent(dir);
 
243
        }
 
244
        QString dir;
 
245
    };
 
246
    ChdirOnReturn cor(QDir::currentPath());
 
247
 
 
248
    QDir::setCurrent("/home");
 
249
    // QTemporaryDir("tempXXXXXX") is probably a bad idea in any app
 
250
    // where the current dir could anything...
 
251
    QTemporaryDir dir("tempXXXXXX");
 
252
    dir.setAutoRemove(true);
 
253
    QVERIFY(!dir.isValid());
 
254
    QVERIFY(dir.path().isEmpty());
 
255
#endif
 
256
}
 
257
 
 
258
void tst_QTemporaryDir::openOnRootDrives()
 
259
{
 
260
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
 
261
    unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
 
262
#endif
 
263
    // If it's possible to create a file in the root directory, it
 
264
    // must be possible to create a temp dir there too.
 
265
    foreach (const QFileInfo &driveInfo, QDir::drives()) {
 
266
        QFile testFile(driveInfo.filePath() + "XXXXXX");
 
267
        if (testFile.open(QIODevice::ReadWrite)) {
 
268
            testFile.remove();
 
269
            QTemporaryDir dir(driveInfo.filePath() + "XXXXXX");
 
270
            dir.setAutoRemove(true);
 
271
            QVERIFY(dir.isValid());
 
272
        }
 
273
    }
 
274
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
 
275
    SetErrorMode(lastErrorMode);
 
276
#endif
 
277
}
 
278
 
 
279
void tst_QTemporaryDir::stressTest()
 
280
{
 
281
    const int iterations = 1000;
 
282
 
 
283
    QSet<QString> names;
 
284
    for (int i = 0; i < iterations; ++i) {
 
285
        QTemporaryDir dir;
 
286
        dir.setAutoRemove(false);
 
287
        QVERIFY2(dir.isValid(), qPrintable(QString::number(i)));
 
288
        QVERIFY(!names.contains(dir.path()));
 
289
        names.insert(dir.path());
 
290
    }
 
291
    for (QSet<QString>::const_iterator it = names.constBegin(); it != names.constEnd(); ++it)
 
292
        QDir(*it).removeRecursively();
 
293
}
 
294
 
 
295
void tst_QTemporaryDir::rename()
 
296
{
 
297
    // This test checks what happens if the temporary dir is renamed.
 
298
    // Then the autodelete feature can't possibly find it.
 
299
 
 
300
    QDir dir;
 
301
    QVERIFY(!dir.exists("temporary-dir.renamed"));
 
302
 
 
303
    QString tempname;
 
304
    {
 
305
        QTemporaryDir tempDir(dir.filePath("temporary-dir.XXXXXX"));
 
306
 
 
307
        QVERIFY(tempDir.isValid());
 
308
        tempname = tempDir.path();
 
309
 
 
310
        QVERIFY(QDir().rename(tempname, "temporary-dir.renamed"));
 
311
        QVERIFY(!QDir(tempname).exists());
 
312
        dir.setPath("temporary-dir.renamed");
 
313
        QCOMPARE(dir.path(), QString("temporary-dir.renamed"));
 
314
        QVERIFY(dir.exists());
 
315
    }
 
316
 
 
317
    // Auto-delete couldn't find it
 
318
    QVERIFY(dir.exists());
 
319
    // Clean up by hand
 
320
    QVERIFY(dir.removeRecursively());
 
321
    QVERIFY(!dir.exists());
 
322
}
 
323
 
 
324
void tst_QTemporaryDir::QTBUG_4796_data()
 
325
{
 
326
    QTest::addColumn<QString>("prefix");
 
327
    QTest::addColumn<QString>("suffix");
 
328
    QTest::addColumn<bool>("openResult");
 
329
 
 
330
    QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
 
331
 
 
332
    QTest::newRow("<empty>") << QString() << QString() << true;
 
333
    QTest::newRow(".") << QString(".") << QString() << true;
 
334
    QTest::newRow("..") << QString("..") << QString() << true;
 
335
    QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
 
336
    QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
 
337
    QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true;
 
338
    QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
 
339
}
 
340
 
 
341
void tst_QTemporaryDir::QTBUG_4796() // unicode support
 
342
{
 
343
    QVERIFY(QDir("test-XXXXXX").exists());
 
344
 
 
345
    struct CleanOnReturn
 
346
    {
 
347
        ~CleanOnReturn()
 
348
        {
 
349
            foreach (const QString &tempName, tempNames)
 
350
                QVERIFY(QDir(tempName).removeRecursively());
 
351
        }
 
352
 
 
353
        void reset()
 
354
        {
 
355
            tempNames.clear();
 
356
        }
 
357
 
 
358
        QStringList tempNames;
 
359
    };
 
360
 
 
361
    CleanOnReturn cleaner;
 
362
 
 
363
    QFETCH(QString, prefix);
 
364
    QFETCH(QString, suffix);
 
365
    QFETCH(bool, openResult);
 
366
 
 
367
    {
 
368
        QString fileTemplate1 = prefix + QString("XX") + suffix;
 
369
        QString fileTemplate2 = prefix + QString("XXXX") + suffix;
 
370
        QString fileTemplate3 = prefix + QString("XXXXXX") + suffix;
 
371
        QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix;
 
372
 
 
373
        QTemporaryDir dir1(fileTemplate1);
 
374
        QTemporaryDir dir2(fileTemplate2);
 
375
        QTemporaryDir dir3(fileTemplate3);
 
376
        QTemporaryDir dir4(fileTemplate4);
 
377
        QTemporaryDir dir5("test-XXXXXX/" + fileTemplate1);
 
378
        QTemporaryDir dir6("test-XXXXXX/" + fileTemplate3);
 
379
 
 
380
        QCOMPARE(dir1.isValid(), openResult);
 
381
        QCOMPARE(dir2.isValid(), openResult);
 
382
        QCOMPARE(dir3.isValid(), openResult);
 
383
        QCOMPARE(dir4.isValid(), openResult);
 
384
        QCOMPARE(dir5.isValid(), openResult);
 
385
        QCOMPARE(dir6.isValid(), openResult);
 
386
 
 
387
        // make sure the dir exists under the *correct* name
 
388
        if (openResult) {
 
389
            cleaner.tempNames << dir1.path()
 
390
                << dir2.path()
 
391
                << dir3.path()
 
392
                << dir4.path()
 
393
                << dir5.path()
 
394
                << dir6.path();
 
395
 
 
396
            QDir currentDir;
 
397
            QString fileName1 = currentDir.relativeFilePath(dir1.path());
 
398
            QString fileName2 = currentDir.relativeFilePath(dir2.path());
 
399
            QString fileName3 = currentDir.relativeFilePath(dir3.path());
 
400
            QString fileName4 = currentDir.relativeFilePath(dir4.path());
 
401
            QString fileName5 = currentDir.relativeFilePath(dir5.path());
 
402
            QString fileName6 = currentDir.relativeFilePath(dir6.path());
 
403
 
 
404
            QVERIFY(fileName1.startsWith(prefix));
 
405
            QVERIFY(fileName2.startsWith(prefix));
 
406
            QVERIFY(fileName5.startsWith("test-XXXXXX/" + prefix));
 
407
            QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix));
 
408
 
 
409
            if (!prefix.isEmpty()) {
 
410
                QVERIFY(fileName3.startsWith(prefix));
 
411
                QVERIFY(fileName4.startsWith(prefix));
 
412
            }
 
413
        }
 
414
    }
 
415
 
 
416
#ifdef Q_OS_WIN
 
417
    QTest::qWait(20);
 
418
#endif
 
419
    foreach (const QString &tempName, cleaner.tempNames)
 
420
        QVERIFY2(!QDir(tempName).exists(), qPrintable(tempName));
 
421
 
 
422
    cleaner.reset();
 
423
}
 
424
 
 
425
QTEST_MAIN(tst_QTemporaryDir)
 
426
#include "tst_qtemporarydir.moc"