|
10 | 10 |
|
11 | 11 | #include <QtTest> |
12 | 12 |
|
| 13 | +#include <QSignalSpy> |
| 14 | +#include <QTemporaryDir> |
| 15 | + |
| 16 | +#include <array> |
| 17 | +#include <climits> |
| 18 | +#include <sys/inotify.h> |
| 19 | +#include <unistd.h> |
| 20 | + |
| 21 | +#define private public |
| 22 | +#define protected public |
13 | 23 | #include "folderwatcher_linux.h" |
| 24 | +#undef protected |
| 25 | +#undef private |
14 | 26 | #include "common/utility.h" |
15 | 27 |
|
16 | 28 | using namespace OCC; |
@@ -64,6 +76,41 @@ private slots: |
64 | 76 | QVERIFY2(ok, "findFoldersBelow failed."); |
65 | 77 | } |
66 | 78 |
|
| 79 | + void testStaleWatchDescriptorIsIgnored() |
| 80 | + { |
| 81 | + QTemporaryDir root; |
| 82 | + QVERIFY2(root.isValid(), "failed to create temp dir"); |
| 83 | + QVERIFY(QDir(root.path()).mkpath("sentinel")); |
| 84 | + |
| 85 | + FolderWatcher watcher; |
| 86 | + watcher.init(root.path()); |
| 87 | + const auto initialWatchCount = watcher.testLinuxWatchCount(); |
| 88 | + QSignalSpy pathChangedSpy(&watcher, &FolderWatcher::pathChanged); |
| 89 | + pathChangedSpy.clear(); |
| 90 | + QVERIFY(!watcher._d->_watchToPath.contains(INT_MAX)); |
| 91 | + |
| 92 | + std::array<int, 2> pipeFds {}; |
| 93 | + QVERIFY(::pipe(pipeFds.data()) == 0); |
| 94 | + |
| 95 | + QByteArray payload(sizeof(inotify_event) + sizeof("lib"), '\0'); |
| 96 | + auto *event = reinterpret_cast<inotify_event *>(payload.data()); |
| 97 | + event->wd = INT_MAX; |
| 98 | + event->mask = IN_CREATE; |
| 99 | + event->cookie = 0; |
| 100 | + event->len = sizeof("lib"); |
| 101 | + memcpy(event->name, "lib", sizeof("lib")); |
| 102 | + |
| 103 | + QCOMPARE(::write(pipeFds[1], payload.constData(), payload.size()), payload.size()); |
| 104 | + watcher._d->slotReceivedNotification(pipeFds[0]); |
| 105 | + |
| 106 | + ::close(pipeFds[0]); |
| 107 | + ::close(pipeFds[1]); |
| 108 | + |
| 109 | + QCOMPARE(watcher.testLinuxWatchCount(), initialWatchCount); |
| 110 | + QCOMPARE(pathChangedSpy.count(), 0); |
| 111 | + QVERIFY(!watcher._d->_watchToPath.contains(INT_MAX)); |
| 112 | + } |
| 113 | + |
67 | 114 | void cleanupTestCase() { |
68 | 115 | if( _root.startsWith(QDir::tempPath() )) { |
69 | 116 | system( QStringLiteral("rm -rf %1").arg(_root).toLocal8Bit() ); |
|
0 commit comments