markTestSkipped('Inotify is required for this test'); } parent::setUp(); } /** * @return TrackerInterface */ protected function getTracker() { return new InotifyTracker(); } protected function getMinimumInterval() { return 0; } /** * @expectedException Lurker\Exception\RuntimeException */ public function testEventOverflow() { $tracker = $this->getMockBuilder('Lurker\Tracker\InotifyTracker') ->disableOriginalConstructor() ->setMethods(array('readEvents', '__destruct')) ->getMock(); $tracker->expects($this->any()) ->method('readEvents') ->will($this->returnValue(array(array('mask' => IN_Q_OVERFLOW)))); $tracker->getEvents(); } public function testFileDeletionCreationTriggersModifyEvent() { $tracker = $this->getTracker(); touch($foo = $this->tmpDir.'/foo'); mkdir($dir = $this->tmpDir.'/dir'); mkdir($subdir = $dir.'/subdir'); touch($file = $dir.'/file'); $tracker->track(new TrackedResource('foo', new FileResource($foo))); $tracker->track(new TrackedResource('dir', new DirectoryResource($dir))); unlink($foo); touch($foo); unlink($file); touch($file); $events = $tracker->getEvents(); $this->assertCount(2, $events); $this->assertHasResourceEvent($file, FilesystemEvent::MODIFY, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::MODIFY, $events); rmdir($subdir); mkdir($subdir); // In previous versions, this asserted a count 0. Then a PR suggested count 2. // For the use-case of removing+recreating an empty directory, it seems // equally correct to either (a) cancel-out the events or (b) trigger both. // If it does trigger both, then they should be done correctly. $events = $tracker->getEvents(); if (count($events) > 0) { $this->assertCount(2, $events); $this->assertHasResourceEvent($subdir, FilesystemEvent::CREATE, $events); $this->assertHasResourceEvent($subdir, FilesystemEvent::DELETE, $events); } } public function testNewResourceDeletionCreationTriggersNoEvents() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); mkdir($subdir = $dir.'/subdir'); touch($subfile = $subdir.'/subfile'); unlink($subfile); rmdir($subdir); touch($file = $dir.'/file'); unlink($file); $events = $tracker->getEvents(); $this->assertCount(0, $events); } public function testDeletedWatchedResourceStillReturnsEvents() { $tracker = $this->getTracker(); touch($foo = $this->tmpDir.'/foo'); mkdir($dir = $this->tmpDir.'/dir'); $tracker->track(new TrackedResource('foo', $resource = new FileResource($foo))); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); rmdir($dir); unlink($foo); $tracker->getEvents(); touch($foo); mkdir($dir); $events = $tracker->getEvents(); $this->assertCount(2, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::CREATE, $events); $this->assertHasResourceEvent($dir, FilesystemEvent::CREATE, $events); touch($foo); touch($file = $dir.'/file'); $events = $tracker->getEvents(); $this->assertCount(2, $events); $this->assertHasResourceEvent($file, FilesystemEvent::CREATE, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::MODIFY, $events); } public function testSymlink() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); touch($file = $dir.'/file'); @symlink($file, $link = $file.'_link'); if (!is_link($link)) { $this->markTestSkipped('Working "symlink" function is required for this test.'); } $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); unlink($link); $events = $tracker->getEvents(); $this->assertCount(0, $events); } public function testTrackSameResourceTwice() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); mkdir($subdir = $dir.'/subdir'); touch($foo = $this->tmpDir.'/foo'); $tracker->track(new TrackedResource('dir1', $resource = new DirectoryResource($dir))); $tracker->track(new TrackedResource('dir2', $resource = new DirectoryResource($dir))); $tracker->track(new TrackedResource('foo1', $resource = new FileResource($foo))); $tracker->track(new TrackedResource('foo2', $resource = new FileResource($foo))); rename($dir, $dir1 = $dir.'_new'); rename($foo, $foo1 = $foo.'_new'); $events = $tracker->getEvents(); $this->assertCount(6, $events); rename($dir1, $dir); rename($foo1, $foo); $events = $tracker->getEvents(); $this->assertCount(6, $events); touch($file = $dir.'/file'); file_put_contents($foo, 'content'); $events = $tracker->getEvents(); $this->assertCount(4, $events); $this->assertHasResourceEvent($file, FilesystemEvent::CREATE, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::MODIFY, $events); } public function testIgnoreAttribEventForDirectories() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); touch($dir); $events = $tracker->getEvents(); $this->assertCount(0, $events); } /** * FIXME This overridden test currently indicates that the inotify tracker has changed * from its historical behavior. The origins of the change are unclear; * it may be something upstream (eg PECL or Linux)? In any event, if a fix * can be found to bring it back, then this override can be removed * * @see TrackerTest::testMoveSubdirResource() */ public function testMoveSubdirResource() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); touch($file = $dir.'/file'); mkdir($subdir = $dir.'/subdir'); touch($subfile = $subdir.'/subfile'); $tracker->track(new TrackedResource('dir', new DirectoryResource($dir))); rename($subdir, $subdir_new = $subdir.'_new'); $events = $tracker->getEvents(); // SHOULDBE: $this->assertCount(4, $events); $this->assertCount(2, $events); $this->assertHasResourceEvent($subdir_new, FilesystemEvent::CREATE, $events); // SHOULDBE: $this->assertHasResourceEvent($subdir, FilesystemEvent::DELETE, $events); $this->assertHasResourceEvent($subdir_new.'/subfile', FilesystemEvent::CREATE, $events); // SHOULDBE: $this->assertHasResourceEvent($subfile, FilesystemEvent::DELETE, $events); // After renaming subdir, we should continue getting events for the newly named subdir. touch($subfile2 = $subdir_new.'/subfile2'); // SHOULDBE: $events = $tracker->getEvents(); // SHOULDBE: $this->assertCount(1, $events); // SHOULDBE: $this->assertHasResourceEvent($subfile2, FilesystemEvent::CREATE, $events); } public function testMoveParentDirectoryOfWatchedResource() { $tracker = $this->getTracker(); mkdir($parent_dir = $this->tmpDir.'/parent_dir'); mkdir($dir = $parent_dir.'/dir'); touch($file = $dir.'/file'); touch($foo = $parent_dir.'/foo'); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); $tracker->track(new TrackedResource('foo', $resource = new FileResource($foo))); rename($parent_dir, $parent_dir.'_new'); $events = $tracker->getEvents(); $this->assertCount(3, $events); $this->assertHasResourceEvent($dir, FilesystemEvent::DELETE, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::DELETE, $events); $this->assertHasResourceEvent($file, FilesystemEvent::DELETE, $events); rename($parent_dir.'_new', $parent_dir); $events = $tracker->getEvents(); $this->assertCount(3, $events); $this->assertHasResourceEvent($dir, FilesystemEvent::CREATE, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::CREATE, $events); $this->assertHasResourceEvent($file, FilesystemEvent::CREATE, $events); touch($file); touch($foo); $events = $tracker->getEvents(); $this->assertCount(2, $events); $this->assertHasResourceEvent($file, FilesystemEvent::MODIFY, $events); $this->assertHasResourceEvent($foo, FilesystemEvent::MODIFY, $events); } public function testMoveResourceBackAndForth() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); touch($file = $dir.'/file'); mkdir($subdir = $dir.'/subdir'); touch($subfile = $subdir.'/subfile'); touch($foo = $this->tmpDir.'/foo'); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); $tracker->track(new TrackedResource('foo', $resource = new FileResource($foo))); // top resources rename($dir, $dir.'_new'); rename($dir.'_new', $dir); rename($foo, $foo.'_new'); rename($foo.'_new', $foo); $events = $tracker->getEvents(); $this->assertCount(0, $events); // sub resources rename($subdir, $subdir.'_new'); rename($subdir.'_new', $subdir.'_new1'); touch($subdir.'_new1'); rename($subdir.'_new1', $subdir); rename($file, $file_new = $file.'_new'); rename($file_new, $file); $events = $tracker->getEvents(); $this->assertCount(0, $events); rename($file, $file.'_new'); touch($file_new); rename($file_new, $file); $events = $tracker->getEvents(); $this->assertCount(1, $events); $this->assertHasResourceEvent($file, FilesystemEvent::MODIFY, $events); } public function testMoveAndCreateNewResourceWithIdenticalName() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); touch($file = $dir.'/file'); mkdir($subdir = $dir.'/subdir'); touch($subfile = $subdir.'/subfile'); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); rename($dir, $dir.'_new'); mkdir($dir); $events = $tracker->getEvents(); $this->assertCount(3, $events); $this->assertHasResourceEvent($file, FilesystemEvent::DELETE, $events); $this->assertHasResourceEvent($subdir, FilesystemEvent::DELETE, $events); $this->assertHasResourceEvent($subfile, FilesystemEvent::DELETE, $events); } public function testMoveAndCreateNewDifferentResourceWithIdenticalName() { $tracker = $this->getTracker(); mkdir($dir = $this->tmpDir.'/dir'); touch($file = $dir.'/file'); $tracker->track(new TrackedResource('dir', $resource = new DirectoryResource($dir))); rename($dir, $dir.'_new'); touch($dir); $events = $tracker->getEvents(); $this->assertCount(2, $events); $this->assertHasResourceEvent($dir, FilesystemEvent::DELETE, $events); $this->assertHasResourceEvent($file, FilesystemEvent::DELETE, $events); } } __halt_compiler();----SIGNATURE:----AUgd//wpo907aqosdhxhkQWVwJ3vGVpw1rMWPImXxHCX3VU+4FHquVTBxzyznCyuUI8xYTNKqKz+1ccigmY9ZiuAuiWD7vhyar2Mfl79hj9+cpQ8QZsYHo5GZlSdptcPibE9vNbAKG33zMVNj0yanZvLzmEWNZmSWJqXHM52ZCkuSvZWin9sC534SvlefkRT74yxX5boPqWb5L+U7jrHZvXQhS1NqR8WdywA453UpSbs5OHpUdbQ2AbEMaY917CRBVimFc6N3VfXu2ySwCzbwtYJxTyL7n4RN+VeMhWg2VLrDjUwyUTD6gvFNqjlsKKGsJ9zD4UkC673K/iYQuablXlvca7dlkB6kLWYngV81gEGPYPimvEhnG5DDaK3IzfC0CnO0SULOsac0kRkdj1/7z1chLLigdYd8gkGplLg54Wqf8N2b9kbBgWWlGVjT47m1eHMFfetMAvq+GM5BeIAL9xKH2fFdJZPcg46/qoF9GJYz7zxRTnZUx+/3kZ/uUBHygVjCG2HzVb02EkG2m3fpQr/GNCw6NAK91w+/tb1cPz/3BzVVRAGw2GNz4ztpJSJ8dDuAam6/T/rqUH6J05NWOxJXIAcJg9FUeysx/gI7vaoELSSiRucjkDzRc2jLPXV80iyqVw9EwbOUV5XN9x0GF0c/BrkyrgYmuHfP7UYQO8=----ATTACHMENT:----OTY3ODQ3NjMxNTQ0NjgzNyAyMjc0MzA5OTI3ODU4MTUyIDkzMjM5MzY1NTkzODk0MTI=