File indexing completed on 2024-04-28 05:48:12
0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0002 // SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org> 0003 0004 #include <QDebug> 0005 #include <QProcess> 0006 #include <QTest> 0007 0008 #ifdef Q_OS_LINUX 0009 #include <sys/param.h> 0010 #endif 0011 0012 #include "directoryIterator.h" 0013 #include "test-config.h" 0014 0015 class DirectoryIteratorTest : public QObject 0016 { 0017 Q_OBJECT 0018 QString m_tree = QFINDTESTDATA("iterator-tree"); 0019 private Q_SLOTS: 0020 void testIterate() 0021 { 0022 #if defined(ITERATOR_TREE_WITH_SYMLINK) 0023 const auto withSymlink = true; 0024 #else 0025 const auto withSymlink = false; 0026 #endif 0027 #if defined(ITERATOR_TREE_WITH_LINK) 0028 const auto withLink = true; 0029 #else 0030 const auto withLink = false; 0031 #endif 0032 0033 QMap<QByteArray, DirectoryEntry> entries; 0034 for (const auto &entry : DirectoryIterator(m_tree.toUtf8())) { 0035 qDebug() << entry.name; 0036 QVERIFY(!entries.contains(entry.name)); 0037 entries.insert(entry.name, entry); 0038 } 0039 qDebug() << entries.keys(); 0040 0041 auto expectedEntries = 3; 0042 if (withSymlink) { 0043 ++expectedEntries; 0044 } 0045 if (withLink) { 0046 ++expectedEntries; 0047 } 0048 QCOMPARE(entries.size(), expectedEntries); 0049 0050 QVERIFY(entries.contains(QByteArrayLiteral("foo"))); 0051 0052 QVERIFY(entries.contains(QByteArrayLiteral("Con 자백"))); 0053 const auto dir = entries[QByteArrayLiteral("Con 자백")]; 0054 QVERIFY(dir.isDir); 0055 QVERIFY(!dir.isFile); 0056 QVERIFY(!dir.isSkipable); 0057 // size doesn't matter, it's ignored 0058 0059 QVERIFY(entries.contains(QByteArrayLiteral("bar"))); 0060 const auto file = entries[QByteArrayLiteral("bar")]; 0061 QVERIFY(!file.isDir); 0062 QVERIFY(file.isFile); 0063 QVERIFY(!file.isSkipable); 0064 #ifdef Q_OS_WINDOWS 0065 QCOMPARE(file.size, 7682); 0066 #elif defined(Q_OS_FREEBSD) 0067 // CI keeps changing, we don't assert anything for freebsd. 0068 #else 0069 QCOMPARE(file.size, 16 * DEV_BSIZE); 0070 #endif 0071 0072 if (withSymlink) { 0073 QVERIFY(entries.contains(QByteArrayLiteral("symlink"))); 0074 const auto symlink = entries[QByteArrayLiteral("symlink")]; 0075 QVERIFY(!symlink.isDir); 0076 QVERIFY(!symlink.isFile); 0077 QVERIFY(symlink.isSkipable); 0078 // size of skipables doesn't matter 0079 } 0080 0081 if (withLink) { 0082 QVERIFY(entries.contains(QByteArrayLiteral("link"))); 0083 const auto symlink = entries[QByteArrayLiteral("link")]; 0084 QVERIFY(!symlink.isDir); 0085 QVERIFY(symlink.isFile); 0086 QVERIFY(!symlink.isSkipable); 0087 #ifdef Q_OS_WINDOWS 0088 QCOMPARE(symlink.size, 7682); 0089 #elif defined(Q_OS_FREEBSD) 0090 // CI keeps changing, we don't assert anything for freebsd. 0091 #else 0092 // We don't know the order, but one should be a duplicate 0093 QVERIFY(symlink.isDuplicate || file.isDuplicate); 0094 // Now make sure only one is a duplicate also 0095 QVERIFY(symlink.isDuplicate != file.isDuplicate); 0096 QCOMPARE(symlink.size, 16 * DEV_BSIZE); 0097 #endif 0098 } 0099 } 0100 0101 void testIterateInsideUnicode() 0102 { 0103 QByteArray tree = QFINDTESTDATA("iterator-tree/Con 자백").toUtf8(); 0104 QMap<QByteArray, DirectoryEntry> entries; 0105 for (const auto &entry : DirectoryIterator(tree)) { 0106 qDebug() << entry.name; 0107 QVERIFY(!entries.contains(entry.name)); 0108 entries.insert(entry.name, entry); 0109 } 0110 qDebug() << entries.keys(); 0111 } 0112 0113 // During development there were some bugs with iterating C:/, make sure this finishes eventually and has some entries. 0114 void testCDrive() 0115 { 0116 QMap<QByteArray, DirectoryEntry> entries; 0117 for (const auto &entry : DirectoryIterator(m_tree.toUtf8())) { 0118 QVERIFY(!entries.contains(entry.name)); 0119 entries.insert(entry.name, entry); 0120 } 0121 QVERIFY(entries.size() > 3); // windows, programs, users 0122 } 0123 0124 void testBadPath() 0125 { 0126 for (const auto &entry : DirectoryIterator(QByteArrayLiteral("/tmp/filelighttest1312312312313123123123"))) { 0127 Q_UNUSED(entry); 0128 QVERIFY(false); 0129 } 0130 } 0131 0132 void testSparseFile() 0133 { 0134 QTemporaryDir tmpdir; 0135 QVERIFY(tmpdir.isValid()); 0136 tmpdir.path(); 0137 0138 // cppreference for std::filesystem::resize_file says it will be sparse when possible but that is a lie! 0139 #if defined(Q_OS_WINDOWS) 0140 { 0141 QProcess proc; 0142 proc.setWorkingDirectory(tmpdir.path()); 0143 proc.start(QStringLiteral("fsutil"), {QStringLiteral("File"), QStringLiteral("CreateNew"), QStringLiteral("foo"), QStringLiteral("1000")}); 0144 QVERIFY(proc.waitForFinished()); 0145 } 0146 { 0147 QProcess proc; 0148 proc.setWorkingDirectory(tmpdir.path()); 0149 proc.start(QStringLiteral("fsutil"), {QStringLiteral("Sparse"), QStringLiteral("SetFlag"), QStringLiteral("foo")}); 0150 QVERIFY(proc.waitForFinished()); 0151 } 0152 { 0153 QProcess proc; 0154 proc.setWorkingDirectory(tmpdir.path()); 0155 proc.start(QStringLiteral("fsutil"), 0156 {QStringLiteral("Sparse"), QStringLiteral("SetRange"), QStringLiteral("foo"), QStringLiteral("0"), QStringLiteral("1000")}); 0157 QVERIFY(proc.waitForFinished()); 0158 } 0159 for (const auto &entry : DirectoryIterator(tmpdir.path().toUtf8())) { 0160 QCOMPARE(entry.size, 0); 0161 } 0162 #else 0163 { 0164 QProcess proc; 0165 proc.setWorkingDirectory(tmpdir.path()); 0166 proc.start(QStringLiteral("truncate"), {QStringLiteral("-s"), QStringLiteral("1K"), QStringLiteral("foo")}); 0167 QVERIFY(proc.waitForFinished()); 0168 } 0169 #endif 0170 0171 bool found = false; 0172 for (const auto &entry : DirectoryIterator(tmpdir.path().toUtf8())) { 0173 QCOMPARE(entry.name, QByteArrayLiteral("foo")); 0174 #if defined(Q_OS_FREEBSD) 0175 // CI keeps changing, we don't assert anything for freebsd. 0176 #else 0177 QCOMPARE(entry.size, 0); 0178 #endif 0179 QVERIFY(!found); // only one item 0180 found = true; 0181 } 0182 QVERIFY(found); 0183 } 0184 }; 0185 0186 QTEST_GUILESS_MAIN(DirectoryIteratorTest) 0187 0188 #include "directoryIteratorTest.moc"