File indexing completed on 2024-12-08 12:21:10

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 // This file can only be included once in a given binary
0009 
0010 #include "../src/utils_p.h"
0011 
0012 #include <QDateTime>
0013 #include <QDebug>
0014 #include <QDir>
0015 #include <QStandardPaths>
0016 #include <QTest>
0017 #include <qglobal.h>
0018 #include <qplatformdefs.h>
0019 #ifdef Q_OS_UNIX
0020 #include <utime.h>
0021 #else
0022 #include <sys/utime.h>
0023 #endif
0024 #include <cerrno>
0025 
0026 #include "kioglobal_p.h"
0027 
0028 QString homeTmpDir()
0029 {
0030     const QString dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/kiotests/"));
0031     if (!QFile::exists(dir)) {
0032         const bool ok = QDir().mkpath(dir);
0033         if (!ok) {
0034             qFatal("Couldn't create %s", qPrintable(dir));
0035         }
0036     }
0037     return dir;
0038 }
0039 
0040 static QDateTime s_referenceTimeStamp;
0041 
0042 static void setTimeStamp(const QString &path, const QDateTime &mtime)
0043 {
0044 #ifdef Q_OS_UNIX
0045     // Put timestamp in the past so that we can check that the listing is correct
0046     struct utimbuf utbuf;
0047     utbuf.actime = mtime.toSecsSinceEpoch();
0048     utbuf.modtime = utbuf.actime;
0049     utime(QFile::encodeName(path), &utbuf);
0050     // qDebug( "Time changed for %s", qPrintable( path ) );
0051 #elif defined(Q_OS_WIN)
0052     struct _utimbuf utbuf;
0053     utbuf.actime = mtime.toSecsSinceEpoch();
0054     utbuf.modtime = utbuf.actime;
0055     _wutime(reinterpret_cast<const wchar_t *>(path.utf16()), &utbuf);
0056 #endif
0057 }
0058 
0059 static void createTestFile(const QString &path, bool plainText = false, const QByteArray &customData = {})
0060 {
0061     QDir().mkpath(QFileInfo(path).absolutePath());
0062     QFile f(path);
0063     if (!f.open(QIODevice::WriteOnly)) {
0064         qFatal("Couldn't create %s: %s", qPrintable(path), qPrintable(f.errorString()));
0065     }
0066     QByteArray data(plainText ? "Hello world" : "Hello\0world", 11);
0067     QCOMPARE(data.size(), 11);
0068     f.write(customData.isEmpty() ? data : customData);
0069     f.close();
0070     setTimeStamp(path, s_referenceTimeStamp);
0071 }
0072 
0073 static void createTestSymlink(const QString &path, const QByteArray &target = "/IDontExist")
0074 {
0075     QFile::remove(path);
0076     bool ok = KIOPrivate::createSymlink(QString::fromLatin1(target), path); // broken symlink
0077     if (!ok) {
0078         qFatal("couldn't create symlink: %s", strerror(errno));
0079     }
0080     QT_STATBUF buf;
0081     QVERIFY(QT_LSTAT(QFile::encodeName(path), &buf) == 0);
0082     QVERIFY(Utils::isLinkMask(buf.st_mode));
0083     // qDebug( "symlink %s created", qPrintable( path ) );
0084     QVERIFY(QFileInfo(path).isSymLink());
0085 }
0086 
0087 void createTestPipe(const QString &path)
0088 {
0089 #ifndef Q_OS_WIN
0090     int ok = mkfifo(QFile::encodeName(path), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
0091     if (ok != 0) {
0092         qFatal("couldn't create named pipe: %s", strerror(errno));
0093     }
0094     QT_STATBUF buf;
0095     QVERIFY(QT_LSTAT(QFile::encodeName(path), &buf) == 0);
0096     QVERIFY(S_ISFIFO(buf.st_mode));
0097 #else
0098     // to not change the filecount everywhere in the tests
0099     createTestFile(path);
0100 #endif
0101     QVERIFY(QFileInfo::exists(path));
0102 }
0103 
0104 enum CreateTestDirectoryOptions { DefaultOptions = 0, NoSymlink = 1, Empty = 2 };
0105 static inline void createTestDirectory(const QString &path, CreateTestDirectoryOptions opt = DefaultOptions)
0106 {
0107     QDir dir;
0108     bool ok = dir.mkdir(path);
0109     if (!ok && !dir.exists()) {
0110         qFatal("Couldn't create %s", qPrintable(path));
0111     }
0112 
0113     if ((opt & Empty) == 0) {
0114         createTestFile(path + QStringLiteral("/testfile"));
0115         if ((opt & NoSymlink) == 0) {
0116 #ifndef Q_OS_WIN
0117             createTestSymlink(path + QStringLiteral("/testlink"));
0118             QVERIFY(QFileInfo(path + QStringLiteral("/testlink")).isSymLink());
0119 #else
0120             // to not change the filecount everywhere in the tests
0121             createTestFile(path + QStringLiteral("/testlink"));
0122 #endif
0123         }
0124     }
0125     setTimeStamp(path, s_referenceTimeStamp);
0126 }