summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorNorwegian Rock Cat <qt-info@nokia.com>2009-07-09 09:51:13 (GMT)
committerNorwegian Rock Cat <qt-info@nokia.com>2009-07-23 15:17:02 (GMT)
commit098be4ffcf4c9ba615332f853fd440ea630a4453 (patch)
treee459998a0388289136820c5cc3a2564f01a368d8 /tests
parentf439550632c0552514f73d2778c7920811e225f7 (diff)
downloadQt-098be4ffcf4c9ba615332f853fd440ea630a4453.zip
Qt-098be4ffcf4c9ba615332f853fd440ea630a4453.tar.gz
Qt-098be4ffcf4c9ba615332f853fd440ea630a4453.tar.bz2
Implement an FSEvents-based QFileSystemWatcherEngine
This has been around for a while and really should have been put in earlier. Mac OS X (client) has a much lower ulimit for open files than what some other Unix-like OS's have (in defense it does save memory). However, if you start watching a lot of files, it will start to fall down. You can adjust the ulimit, but it's a bit inconvenient. FSEvents watches the directory and notifies you of changes that happen in that directory (and below, but we don't really use it). It also can be adjusted for latency so that performance isn't affected by heavy file system use (but Qt doesn't use that either at the moment). The other thing is that it doesn't require any open files, so it's much better for our number of open files. This feature is only on Leopard and up, so people wanting to deploy Tiger will still have the "open files" problem to deal with. There are still some optimizations available in this code. For example, we could coalesce things down to watch only one high-level directory without changing much of the implementation. The current implementation has some very simplistic ways of handling things, but this simplicity works well. I documented it, so you can see that, yes, I really meant to do that. Task-Id: 164068 (and others) Reviewed-by: Denis
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index da06742..c883c63 100644
--- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -73,6 +73,8 @@ private slots:
void removePath();
void addPaths();
void removePaths();
+ void watchFileAndItsDirectory();
+ void watchFileAndItsDirectory_data() { basicTest_data(); }
private:
QStringList do_force_engines;
@@ -397,5 +399,83 @@ void tst_QFileSystemWatcher::removePaths()
watcher.removePaths(paths);
}
+void tst_QFileSystemWatcher::watchFileAndItsDirectory()
+{
+ QFETCH(QString, backend);
+ QDir().mkdir("testDir");
+ QDir testDir("testDir");
+
+ QString testFileName = testDir.filePath("testFile.txt");
+ QString secondFileName = testDir.filePath("testFile2.txt");
+ QFile::remove(secondFileName);
+
+ QFile testFile(testFileName);
+ testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
+ testFile.remove();
+
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.write(QByteArray("hello"));
+ testFile.close();
+
+ QFileSystemWatcher watcher;
+ watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
+
+ watcher.addPath(testDir.dirName());
+ watcher.addPath(testFileName);
+
+ QSignalSpy fileChangedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
+ QSignalSpy dirChangedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
+ QEventLoop eventLoop;
+ QTimer timer;
+ connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+
+ // resolution of the modification time is system dependent, but it's at most 1 second when using
+ // the polling engine. From what I know, FAT32 has a 2 second resolution. So we have to
+ // wait before modifying the directory...
+ QTest::qWait(2000);
+
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.write(QByteArray("hello again"));
+ testFile.close();
+
+ timer.start(3000);
+ eventLoop.exec();
+ QCOMPARE(fileChangedSpy.count(), 1);
+ QCOMPARE(dirChangedSpy.count(), 0);
+
+ fileChangedSpy.clear();
+ QFile secondFile(secondFileName);
+ secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ secondFile.write("Foo");
+ secondFile.close();
+
+ timer.start(3000);
+ eventLoop.exec();
+ QCOMPARE(fileChangedSpy.count(), 0);
+ QCOMPARE(dirChangedSpy.count(), 1);
+
+ dirChangedSpy.clear();
+
+ QFile::remove(testFileName);
+
+ timer.start(3000);
+ eventLoop.exec();
+ QCOMPARE(fileChangedSpy.count(), 1);
+ QCOMPARE(dirChangedSpy.count(), 1);
+
+ fileChangedSpy.clear();
+ dirChangedSpy.clear();
+
+ watcher.removePath(testFileName);
+ QFile::remove(secondFileName);
+
+ timer.start(3000);
+ eventLoop.exec();
+ QCOMPARE(fileChangedSpy.count(), 0);
+ QCOMPARE(dirChangedSpy.count(), 1);
+
+ QVERIFY(QDir().rmdir("testDir"));
+}
+
QTEST_MAIN(tst_QFileSystemWatcher)
#include "tst_qfilesystemwatcher.moc"