diff --git a/src/filesystem/__tests__/PhutilDeferredLogTestCase.php b/src/filesystem/__tests__/PhutilDeferredLogTestCase.php --- a/src/filesystem/__tests__/PhutilDeferredLogTestCase.php +++ b/src/filesystem/__tests__/PhutilDeferredLogTestCase.php @@ -94,28 +94,6 @@ $this->assertTrue($caught instanceof Exception); } - public function testManyWriters() { - $root = phutil_get_library_root('arcanist').'/../'; - $bin = $root.'scripts/test/deferred_log.php'; - - $n_writers = 3; - $n_lines = 8; - - $tmp = new TempFile(); - - $futures = array(); - for ($ii = 0; $ii < $n_writers; $ii++) { - $futures[] = new ExecFuture('%s %d %s', $bin, $n_lines, (string)$tmp); - } - - id(new FutureIterator($futures)) - ->resolveAll(); - - $this->assertEqual( - str_repeat("abcdefghijklmnopqrstuvwxyz\n", $n_writers * $n_lines), - Filesystem::readFile($tmp)); - } - public function testNoWrite() { $tmp = new TempFile(); diff --git a/src/filesystem/__tests__/PhutilFileLockTestCase.php b/src/filesystem/__tests__/PhutilFileLockTestCase.php --- a/src/filesystem/__tests__/PhutilFileLockTestCase.php +++ b/src/filesystem/__tests__/PhutilFileLockTestCase.php @@ -172,11 +172,13 @@ private function buildLockFuture($flags, $file) { $root = dirname(phutil_get_library_root('arcanist')); - $bin = $root.'/scripts/utils/lock.php'; + $bin = $root.'/support/test/lock-file.php'; + + $flags = (array)$flags; // NOTE: Use `exec` so this passes on Ubuntu, where the default `dash` shell // will eat any kills we send during the tests. - $future = new ExecFuture('exec php %s %C %s', $bin, $flags, $file); + $future = new ExecFuture('exec php -f %R -- %Ls %R', $bin, $flags, $file); $future->start(); return $future; } diff --git a/support/test/lock-file.php b/support/test/lock-file.php new file mode 100644 --- /dev/null +++ b/support/test/lock-file.php @@ -0,0 +1,82 @@ +#!/usr/bin/env php +setTagline(pht('acquire and hold a lockfile')); +$args->setSynopsis(<<parseStandardArguments(); +$args->parse(array( + array( + 'name' => 'test', + 'help' => pht('Instead of holding the lock, release it and exit.'), + ), + array( + 'name' => 'hold', + 'help' => pht('Hold indefinitely without prompting.'), + ), + array( + 'name' => 'wait', + 'param' => 'n', + 'help' => pht('Block for up to __n__ seconds waiting for the lock.'), + 'default' => 0, + ), + array( + 'name' => 'file', + 'wildcard' => true, + ), +)); + + +$file = $args->getArg('file'); +if (count($file) !== 1) { + $args->printHelpAndExit(); +} +$file = head($file); + +$console = PhutilConsole::getConsole(); +$console->writeOut( + "%s\n", + pht('This process has PID %d. Acquiring lock...', getmypid())); + +$lock = PhutilFileLock::newForPath($file); + +try { + $lock->lock($args->getArg('wait')); +} catch (PhutilFileLockException $ex) { + $console->writeOut( + "**%s** %s\n", + pht('UNABLE TO ACQUIRE LOCK:'), + pht('Lock is already held.')); + exit(1); +} + +// NOTE: This string is magic, the unit tests look for it. +$console->writeOut("%s\n", pht('LOCK ACQUIRED')); +if ($args->getArg('test')) { + $lock->unlock(); + exit(0); +} + +if ($args->getArg('hold')) { + while (true) { + sleep(1); + } +} + +while (!$console->confirm(pht('Release lock?'))) { + // Keep asking until they say yes. +} + +$console->writeOut("%s\n", pht('Unlocking...')); +$lock->unlock(); + +$console->writeOut("%s\n", pht('Done.')); +exit(0);