diff options
author | Norwegian Rock Cat <qt-info@nokia.com> | 2009-07-09 09:51:13 (GMT) |
---|---|---|
committer | Norwegian Rock Cat <qt-info@nokia.com> | 2009-07-23 15:17:02 (GMT) |
commit | 098be4ffcf4c9ba615332f853fd440ea630a4453 (patch) | |
tree | e459998a0388289136820c5cc3a2564f01a368d8 /tests/auto | |
parent | f439550632c0552514f73d2778c7920811e225f7 (diff) | |
download | Qt-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/auto')
-rw-r--r-- | tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 80 |
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" |