File indexing completed on 2024-04-28 03:51:40
0001 /* 0002 SPDX-FileCopyrightText: 2014 Vishesh Handa <me@vhanda.in> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "filewatch.h" 0008 #include "fileindexerconfigutils.h" 0009 #include "database.h" 0010 #include "fileindexerconfig.h" 0011 #include "pendingfilequeue.h" 0012 0013 #include <QTest> 0014 #include <QSignalSpy> 0015 #include <QTemporaryDir> 0016 #include <KFileMetaData/UserMetaData> 0017 0018 namespace Baloo { 0019 0020 class FileWatchTest : public QObject 0021 { 0022 Q_OBJECT 0023 private Q_SLOTS: 0024 0025 void testFileCreation(); 0026 void testConfigChange(); 0027 0028 void init() 0029 { 0030 m_tmpDir = std::make_unique<QTemporaryDir>(); 0031 QVERIFY(m_tmpDir->isValid()); 0032 0033 m_dbDir = std::make_unique<QTemporaryDir>(); 0034 QVERIFY(m_dbDir->isValid()); 0035 0036 m_db = std::make_unique<Baloo::Database>(m_dbDir->path()); 0037 } 0038 0039 private: 0040 std::unique_ptr<QTemporaryDir> m_dbDir; 0041 std::unique_ptr<QTemporaryDir> m_tmpDir; 0042 std::unique_ptr<Baloo::Database> m_db; 0043 }; 0044 0045 } // namespace Baloo 0046 0047 using namespace Baloo; 0048 0049 namespace { 0050 bool createFile(const QString& fileUrl) { 0051 QFile f1(fileUrl); 0052 f1.open(QIODevice::WriteOnly); 0053 f1.close(); 0054 return QFile::exists(fileUrl); 0055 } 0056 0057 void modifyFile(const QString& fileUrl) { 0058 QFile f1(fileUrl); 0059 f1.open(QIODevice::Append | QIODevice::Text); 0060 0061 QTextStream stream(&f1); 0062 stream << "1"; 0063 } 0064 } 0065 0066 void FileWatchTest::testFileCreation() 0067 { 0068 m_db->open(Baloo::Database::CreateDatabase); 0069 QVERIFY(m_db->isOpen()); 0070 0071 Test::writeIndexerConfig({m_tmpDir->path()}, {}); 0072 FileIndexerConfig config; 0073 0074 FileWatch fileWatch(m_db.get(), &config); 0075 fileWatch.m_pendingFileQueue->setMaximumTimeout(0); 0076 fileWatch.m_pendingFileQueue->setMinimumTimeout(0); 0077 fileWatch.m_pendingFileQueue->setTrackingTime(0); 0078 0079 QSignalSpy spy(&fileWatch, &FileWatch::installedWatches); 0080 QVERIFY(spy.isValid()); 0081 0082 fileWatch.updateIndexedFoldersWatches(); 0083 QVERIFY(spy.wait()); 0084 QCOMPARE(spy.count(), 1); 0085 0086 QSignalSpy spyIndexNew(&fileWatch, &FileWatch::indexNewFile); 0087 QSignalSpy spyIndexModified(&fileWatch, &FileWatch::indexModifiedFile); 0088 QSignalSpy spyIndexXattr(&fileWatch, &FileWatch::indexXAttr); 0089 0090 QVERIFY(spyIndexNew.isValid()); 0091 QVERIFY(spyIndexModified.isValid()); 0092 QVERIFY(spyIndexXattr.isValid()); 0093 0094 // Create a file and see if it is indexed 0095 QString fileUrl(m_tmpDir->path() + QStringLiteral("/t1")); 0096 QVERIFY(createFile(fileUrl)); 0097 0098 QVERIFY(spyIndexNew.wait()); 0099 QCOMPARE(spyIndexNew.count(), 1); 0100 QCOMPARE(spyIndexModified.count(), 0); 0101 QCOMPARE(spyIndexXattr.count(), 0); 0102 QCOMPARE(spyIndexNew.takeFirst().at(0), fileUrl); 0103 0104 // Modify the file 0105 modifyFile(fileUrl); 0106 0107 QVERIFY(spyIndexModified.wait()); 0108 QCOMPARE(spyIndexNew.count(), 0); 0109 QCOMPARE(spyIndexModified.count(), 1); 0110 QCOMPARE(spyIndexXattr.count(), 0); 0111 QCOMPARE(spyIndexModified.takeFirst().at(0), fileUrl); 0112 0113 // Set an Xattr 0114 KFileMetaData::UserMetaData umd(fileUrl); 0115 if (!umd.isSupported()) { 0116 qWarning() << "Xattr not supported on this filesystem:" << fileUrl; 0117 } else { 0118 const QString userComment(QStringLiteral("UserComment")); 0119 QVERIFY(umd.setUserComment(userComment) == KFileMetaData::UserMetaData::NoError); 0120 0121 QVERIFY(spyIndexXattr.wait()); 0122 QCOMPARE(spyIndexNew.count(), 0); 0123 QCOMPARE(spyIndexModified.count(), 0); 0124 QCOMPARE(spyIndexXattr.count(), 1); 0125 QCOMPARE(spyIndexXattr.takeFirst().at(0), fileUrl); 0126 } 0127 0128 // Change permisssions 0129 QFile f(fileUrl); 0130 auto permissions = f.permissions(); 0131 f.setPermissions(permissions & ~QFileDevice::WriteOwner); 0132 0133 QVERIFY(spyIndexXattr.wait()); 0134 QCOMPARE(spyIndexNew.count(), 0); 0135 QCOMPARE(spyIndexModified.count(), 0); 0136 QCOMPARE(spyIndexXattr.count(), 1); 0137 QCOMPARE(spyIndexXattr.takeFirst().at(0), fileUrl); 0138 } 0139 0140 void FileWatchTest::testConfigChange() 0141 { 0142 m_db->open(Baloo::Database::CreateDatabase); 0143 0144 QString d1 = m_tmpDir->path() + QStringLiteral("/d1"); 0145 QString d2 = m_tmpDir->path() + QStringLiteral("/d2"); 0146 QString d11 = m_tmpDir->path() + QStringLiteral("/d1/d11"); 0147 QString d21 = m_tmpDir->path() + QStringLiteral("/d2/d21"); 0148 QString d22 = m_tmpDir->path() + QStringLiteral("/d2/d22"); 0149 0150 QDir().mkpath(d11); 0151 QDir().mkpath(d21); 0152 QDir().mkpath(d22); 0153 0154 // parameters: includeFolders list, excludeFolders list 0155 Test::writeIndexerConfig({d1, d2}, {d11, d21}); 0156 FileIndexerConfig config; 0157 0158 FileWatch fileWatch(m_db.get(), &config); 0159 fileWatch.m_pendingFileQueue->setMaximumTimeout(0); 0160 fileWatch.m_pendingFileQueue->setMinimumTimeout(0); 0161 fileWatch.m_pendingFileQueue->setTrackingTime(0); 0162 0163 QSignalSpy spy(&fileWatch, &FileWatch::installedWatches); 0164 QVERIFY(spy.isValid()); 0165 0166 fileWatch.updateIndexedFoldersWatches(); 0167 QVERIFY(spy.wait()); 0168 QCOMPARE(spy.count(), 2); 0169 0170 QSignalSpy spyIndexNew(&fileWatch, &FileWatch::indexNewFile); 0171 QVERIFY(spyIndexNew.isValid()); 0172 QVERIFY(createFile(d1 + QStringLiteral("/t1"))); 0173 QVERIFY(createFile(d2 + QStringLiteral("/t2"))); 0174 0175 QVERIFY(spyIndexNew.wait()); 0176 QCOMPARE(spyIndexNew.count(), 2); 0177 spyIndexNew.clear(); 0178 0179 // dir d22 is not yet excluded, so one event is expected 0180 QVERIFY(createFile(d11 + QStringLiteral("/tx1"))); 0181 QVERIFY(createFile(d21 + QStringLiteral("/tx2"))); 0182 QVERIFY(createFile(d22 + QStringLiteral("/tx3"))); 0183 0184 QVERIFY(spyIndexNew.wait()); 0185 QCOMPARE(spyIndexNew.count(), 1); 0186 QList<QVariant> event = spyIndexNew.at(0); 0187 QCOMPARE(event.at(0).toString(), d22 + QStringLiteral("/tx3")); 0188 spyIndexNew.clear(); 0189 0190 Test::writeIndexerConfig({d2}, {d22}); 0191 config.forceConfigUpdate(); 0192 fileWatch.updateIndexedFoldersWatches(); 0193 0194 // dir d1 is no longer included 0195 QVERIFY(createFile(d1 + QStringLiteral("/tx1a"))); 0196 QVERIFY(createFile(d2 + QStringLiteral("/tx2a"))); 0197 QVERIFY(spyIndexNew.wait()); 0198 QList<QString> result; 0199 for (const QList<QVariant>& event : std::as_const(spyIndexNew)) { 0200 result.append(event.at(0).toString()); 0201 } 0202 QCOMPARE(result, {d2 + QStringLiteral("/tx2a")}); 0203 spyIndexNew.clear(); 0204 result.clear(); 0205 0206 // d11 is implicitly excluded, as d1 is no longer included 0207 // d22 is explicitly excluded now, d21 is included 0208 QVERIFY(createFile(d11 + QStringLiteral("/tx1b"))); 0209 QVERIFY(createFile(d21 + QStringLiteral("/tx2b"))); 0210 QVERIFY(createFile(d22 + QStringLiteral("/tx3b"))); 0211 0212 QVERIFY(spyIndexNew.wait(500)); 0213 for (const QList<QVariant>& event : std::as_const(spyIndexNew)) { 0214 result.append(event.at(0).toString()); 0215 } 0216 QCOMPARE(result, {d21 + QStringLiteral("/tx2b")}); 0217 } 0218 0219 QTEST_MAIN(FileWatchTest) 0220 0221 #include "filewatchtest.moc"