function testTwoDeep() { $dir = new WatchmanDirectoryFixture(); $root = $dir->getPath(); $watch = $this->watch($root); $this->assertFileList($root, array()); $this->assertEqual(true, mkdir("{$root}/foo")); $this->assertEqual(true, mkdir("{$root}/foo/bar")); // Guarantee that 111's mtime is greater than its directory's sleep(1); $this->assertEqual(3, file_put_contents("{$root}/foo/bar/111", "111")); $this->watchmanCommand('log', 'debug', 'XXX: created 111'); $this->assertFileList($root, array("foo", "foo/bar", "foo/bar/111")); $query = $this->watchmanCommand('find', $root, 'foo/bar/111'); $wfile = $query['files'][0]; clearstatcache(); $sfile = stat("{$root}/foo/bar/111"); $query = $this->watchmanCommand('find', $root, 'foo/bar'); $wdir = $query['files'][0]; clearstatcache(); $sdir = stat("{$root}/foo/bar"); $this->watchmanCommand('log', 'debug', 'XXX: perform assertions'); $compare_fields = array('size', 'mode', 'uid', 'gid', 'ino', 'dev', 'nlink', 'mtime', 'ctime'); foreach ($compare_fields as $field) { $this->assertEqual($sfile[$field], $wfile[$field], "file: {$field} {$sfile[$field]} vs watchman {$wfile[$field]}"); $this->assertEqual($sdir[$field], $wdir[$field], "dir: {$field} {$sdir[$field]} vs watchman {$wdir[$field]}"); } $this->watchmanCommand('log', 'debug', 'XXX: remove it all'); w_rmdir_recursive("{$root}/foo/bar"); $this->assertFileList($root, array("foo")); }
function w_rmdir_recursive_inner($path) { # avoid opening a handle on the dir in case that impacts # delete latency on windows if (@rmdir($path) || @unlink($path)) { return true; } clearstatcache(); if (is_dir($path)) { # most likely failure reason is that the dir is not empty $kids = @scandir($path); if (is_array($kids)) { foreach ($kids as $kid) { if ($kid == '.' || $kid == '..') { continue; } w_rmdir_recursive($path . DIRECTORY_SEPARATOR . $kid); } } if (is_dir($path)) { return @rmdir($path); } } if (is_file($path)) { return unlink($path); } return !file_exists($path); }
function testRemoveRoot() { if (PHP_OS == 'Linux' && getenv('TRAVIS')) { $this->assertSkipped('openvz and inotify unlinks == bad time'); } $dir = new WatchmanDirectoryFixture(); $top = $dir->getPath(); $root = $top . DIRECTORY_SEPARATOR . "root"; mkdir($root); touch("{$root}/hello"); $this->watch($root); $this->assertFileList($root, array('hello')); w_rmdir_recursive($root); $this->assertFileList($root, array()); $watches = $this->waitForWatchman(array('watch-list'), function ($list) use($root) { return !in_array($root, $list['roots']); }); $this->assertEqual(false, in_array($root, $watches['roots']), "watch deleted"); // Really need to ensure that we mkdir, otherwise the $dir fixture // will throw when the scope unwinds $this->waitFor(function () use($root) { return @mkdir($root); }, 10, "mkdir({$root}) to succeed"); touch("{$root}/hello"); $this->assertFileList($root, array()); }
function testMoveReAdd() { if (PHP_OS == 'Linux' && getenv('TRAVIS')) { $this->assertSkipped('openvz and inotify unlinks == bad time'); } $dir = new WatchmanDirectoryFixture(); $root = $dir->getPath(); mkdir("{$root}/foo"); $watch = $this->watch($root); $this->assertFileListUsingSince($root, 'n:foo', array('foo'), array('foo')); $this->watchmanCommand('log', 'debug', 'XXX: touch foo/222'); touch("{$root}/foo/222"); $this->assertFileListUsingSince($root, 'n:foo', array('foo', 'foo/222'), array('foo/222')); $this->watchmanCommand('log', 'debug', 'XXX: mkdir foo/bar'); mkdir("{$root}/foo/bar"); $since = array('foo/bar'); if (in_array($watch['watcher'], array('win32', 'portfs', 'kqueue'))) { // the parent dir reflects as changed when we mkdir within it array_unshift($since, 'foo'); } $this->assertFileListUsingSince($root, 'n:foo', array('foo', 'foo/222', 'foo/bar'), $since); $this->watchmanCommand('log', 'debug', 'XXX: rmdir foo/bar'); w_rmdir_recursive("{$root}/foo/bar"); $this->watchmanCommand('log', 'debug', 'XXX: unlink foo/222'); unlink("{$root}/foo/222"); $this->watchmanCommand('log', 'debug', 'XXX: rmdir foo'); w_rmdir_recursive("{$root}/foo"); $this->assertFileListUsingSince($root, 'n:foo', array(), array()); $this->watchmanCommand('log', 'debug', 'XXX: mkdir foo'); mkdir("{$root}/foo"); $this->watchmanCommand('log', 'debug', 'XXX: touch foo/222'); touch("{$root}/foo/222"); $this->assertFileListUsingSince($root, 'n:foo', array("foo", "foo/222"), array("foo", "foo/222")); }
function testAge1() { $dir = new WatchmanDirectoryFixture(); $root = $dir->getPath(); mkdir("{$root}/a"); touch("{$root}/a/file.txt"); touch("{$root}/b.txt"); $this->watch($root); $this->assertFileList($root, array('a', 'a/file.txt', 'b.txt')); $res = $this->watchmanCommand('query', $root, array('fields' => array('name', 'exists'))); $this->assertEqual(true, $res['is_fresh_instance']); $clock = $res['clock']; // Removing file nodes also impacts the suffix list, so we test // that it is operating as intended in here too $res = $this->watchmanCommand('query', $root, array('expression' => array('suffix', 'txt'), 'fields' => array('name'))); $this->assertEqualFileList(array('a/file.txt', 'b.txt'), $res['files']); // Let's track a named cursor; we need to validate that it is // correctly aged out $this->watchmanCommand('since', $root, 'n:foo'); $cursors = $this->watchmanCommand('debug-show-cursors', $root); $this->assertTrue(array_key_exists('n:foo', $cursors['cursors'])); unlink("{$root}/a/file.txt"); w_rmdir_recursive("{$root}/a"); $this->assertFileList($root, array('b.txt')); // Prune all deleted items $this->watchmanCommand('debug-ageout', $root, 0); // Wait for 'a' to age out and cause is_fresh_instance to be set $res = $this->waitForWatchman(array('query', $root, array('since' => $clock, 'fields' => array('name', 'exists'))), function ($list) { return idx($list, 'is_fresh_instance') === true; }); // Verify that the file list is what we expect $this->assertFileListUsingSince($root, $clock, array('b.txt')); // Our cursor should have been collected $cursors = $this->watchmanCommand('debug-show-cursors', $root); $this->assertFalse(array_key_exists('n:foo', $cursors['cursors'])); // Add a new file to the suffix list; this will insert at the head touch("{$root}/c.txt"); // suffix query to verify that linkage is safe $res = $this->watchmanCommand('query', $root, array('expression' => array('suffix', 'txt'), 'fields' => array('name'))); sort($res['files']); $this->assertEqual(array('b.txt', 'c.txt'), $res['files']); for ($attempts = 0; $attempts < 3; $attempts++) { // Let's stress it a bit mkdir("{$root}/dir"); for ($i = 0; $i < 100; $i++) { touch("{$root}/stress-{$i}"); touch("{$root}/dir/{$i}"); } for ($i = 0; $i < 100; $i++) { w_rmdir_recursive("{$root}/stress-{$i}"); } w_rmdir_recursive("{$root}/dir"); $this->assertFileList($root, array('b.txt', 'c.txt')); $this->watchmanCommand('debug-ageout', $root, 0); $this->assertFileList($root, array('b.txt', 'c.txt')); } }
function testRemove() { $dir = new WatchmanDirectoryFixture(); $root = $dir->getPath(); mkdir("{$root}/one"); touch("{$root}/one/onefile"); mkdir("{$root}/one/two"); touch("{$root}/one/two/twofile"); touch("{$root}/top"); $this->watch($root); $this->assertFileList($root, array('one', 'one/onefile', 'one/two', 'one/two/twofile', 'top')); $this->watchmanCommand('log', 'debug', 'XXX: remove dir one'); w_rmdir_recursive("{$root}/one"); $this->assertFileList($root, array('top')); $this->watchmanCommand('log', 'debug', 'XXX: touch file one'); touch("{$root}/one"); $this->assertFileList($root, array('one', 'top')); $this->watchmanCommand('log', 'debug', 'XXX: unlink file one'); unlink("{$root}/one"); $this->assertFileList($root, array('top')); if (phutil_is_windows()) { // This looks so fugly system("rd /s /q {$root}"); for ($i = 0; $i < 10; $i++) { if (!is_dir($root)) { break; } usleep(20000); } for ($i = 0; $i < 10; $i++) { if (@mkdir("{$root}")) { break; } usleep(20000); } @mkdir("{$root}/notme"); } else { system("rm -rf {$root} ; mkdir -p {$root}/notme"); } if (PHP_OS == 'Linux' && getenv('TRAVIS')) { $this->assertSkipped('openvz and inotify unlinks == bad time'); } $watches = $this->waitForWatchman(array('watch-list'), function ($list) use($root) { return !in_array($root, $list['roots']); }); $this->assertEqual(false, in_array($root, $watches['roots']), "watch deleted"); }
function w_rmdir_recursive($path) { clearstatcache(); if (is_dir($path)) { $kids = @scandir($path); if (is_array($kids)) { foreach ($kids as $kid) { if ($kid == '.' || $kid == '..') { continue; } w_rmdir_recursive($path . DIRECTORY_SEPARATOR . $kid); } } if (is_dir($path)) { return @rmdir($path); } } if (is_file($path)) { return unlink($path); } return !file_exists($path); }