Console Lock
WIP
This commit is contained in:
parent
425876316f
commit
41e2031e6b
9 changed files with 420 additions and 25 deletions
185
src/Console/Lock.php
Normal file
185
src/Console/Lock.php
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Friendica\Console;
|
||||||
|
|
||||||
|
use Asika\SimpleConsole\CommandArgsException;
|
||||||
|
use Friendica\App;
|
||||||
|
use Friendica\Core\Lock\ILock;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief tool to access the locks from the CLI
|
||||||
|
*
|
||||||
|
* With this script you can access the locks of your node from the CLI.
|
||||||
|
* You can read current locks and set/remove locks.
|
||||||
|
*
|
||||||
|
* @author Philipp Holzer <admin@philipp.info>, Hypolite Petovan <hypolite@mrpetovan.com>
|
||||||
|
*/
|
||||||
|
class Lock extends \Asika\SimpleConsole\Console
|
||||||
|
{
|
||||||
|
protected $helpOptions = ['h', 'help', '?'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var App\Mode
|
||||||
|
*/
|
||||||
|
private $appMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ILock
|
||||||
|
*/
|
||||||
|
private $lock;
|
||||||
|
|
||||||
|
protected function getHelp()
|
||||||
|
{
|
||||||
|
$help = <<<HELP
|
||||||
|
console cache - Manage node cache
|
||||||
|
Synopsis
|
||||||
|
bin/console lock list [<prefix>] [-h|--help|-?] [-v]
|
||||||
|
bin/console lock set <lock> [<timeout> [<ttl>]] [-h|--help|-?] [-v]
|
||||||
|
bin/console lock del <lock> [-h|--help|-?] [-v]
|
||||||
|
bin/console lock clear [-h|--help|-?] [-v]
|
||||||
|
|
||||||
|
Description
|
||||||
|
bin/console lock list [<prefix>]
|
||||||
|
List all locks, optionally filtered by a prefix
|
||||||
|
|
||||||
|
bin/console lock set <lock> [<timeout> [<ttl>]]
|
||||||
|
Sets manually a lock, optionally with the provided TTL (time to live) with a default of five minutes.
|
||||||
|
|
||||||
|
bin/console lock del <lock>
|
||||||
|
Deletes a lock.
|
||||||
|
|
||||||
|
bin/console lock clear
|
||||||
|
Clears all locks
|
||||||
|
|
||||||
|
Options
|
||||||
|
-h|--help|-? Show help information
|
||||||
|
-v Show more debug information.
|
||||||
|
HELP;
|
||||||
|
return $help;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(App\Mode $appMode, ILock $lock, array $argv = null)
|
||||||
|
{
|
||||||
|
parent::__construct($argv);
|
||||||
|
|
||||||
|
$this->appMode = $appMode;
|
||||||
|
$this->lock = $lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function doExecute()
|
||||||
|
{
|
||||||
|
if ($this->getOption('v')) {
|
||||||
|
$this->out('Executable: ' . $this->executable);
|
||||||
|
$this->out('Class: ' . __CLASS__);
|
||||||
|
$this->out('Arguments: ' . var_export($this->args, true));
|
||||||
|
$this->out('Options: ' . var_export($this->options, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->appMode->has(App\Mode::DBCONFIGAVAILABLE)) {
|
||||||
|
$this->out('Database isn\'t ready or populated yet, database cache won\'t be available');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getOption('v')) {
|
||||||
|
$this->out('Lock Driver Name: ' . $this->lock->getName());
|
||||||
|
$this->out('Lock Driver Class: ' . get_class($this->lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($this->getArgument(0)) {
|
||||||
|
case 'list':
|
||||||
|
$this->executeList();
|
||||||
|
break;
|
||||||
|
case 'set':
|
||||||
|
$this->executeSet();
|
||||||
|
break;
|
||||||
|
case 'del':
|
||||||
|
$this->executeDel();
|
||||||
|
break;
|
||||||
|
case 'clear':
|
||||||
|
$this->executeClear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->args) == 0) {
|
||||||
|
$this->out($this->getHelp());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function executeList()
|
||||||
|
{
|
||||||
|
$prefix = $this->getArgument(1, '');
|
||||||
|
$keys = $this->lock->getLocks($prefix);
|
||||||
|
|
||||||
|
if (empty($prefix)) {
|
||||||
|
$this->out('Listing all Locks:');
|
||||||
|
} else {
|
||||||
|
$this->out('Listing all Locks starting with "' . $prefix . '":');
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$this->out($key);
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out($count . ' locks found');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function executeDel()
|
||||||
|
{
|
||||||
|
if (count($this->args) >= 2) {
|
||||||
|
$lock = $this->getArgument(1);
|
||||||
|
|
||||||
|
if ($this->lock->releaseLock($lock, true)){
|
||||||
|
$this->out(sprintf('Lock \'%s\' released.', $lock));
|
||||||
|
} else {
|
||||||
|
$this->out(sprintf('Couldn\'t release Lock \'%s\'', $lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new CommandArgsException('Too few arguments for del.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function executeSet()
|
||||||
|
{
|
||||||
|
if (count($this->args) >= 2) {
|
||||||
|
$lock = $this->getArgument(1);
|
||||||
|
$timeout = intval($this->getArgument(2, false));
|
||||||
|
$ttl = intval($this->getArgument(3, false));
|
||||||
|
|
||||||
|
if (is_array($this->lock->isLocked($lock))) {
|
||||||
|
throw new RuntimeException(sprintf('\'%s\' is already set.', $lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($ttl) && !empty($timeout)) {
|
||||||
|
$result = $this->lock->acquireLock($lock, $timeout, $ttl);
|
||||||
|
} elseif (!empty($timeout)) {
|
||||||
|
$result = $this->lock->acquireLock($lock, $timeout);
|
||||||
|
} else {
|
||||||
|
$result = $this->lock->acquireLock($lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
$this->out(sprintf('Lock \'%s\' acquired.', $lock));
|
||||||
|
} else {
|
||||||
|
$this->out(sprintf('Unable to lock \'%s\'', $lock));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new CommandArgsException('Too few arguments for set.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function executeClear()
|
||||||
|
{
|
||||||
|
$result = $this->lock->releaseAll(true);
|
||||||
|
if ($result) {
|
||||||
|
$this->out('Locks successfully cleared,');
|
||||||
|
} else {
|
||||||
|
$this->out('Unable to clear the locks.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ Commands:
|
||||||
archivecontact Archive a contact when you know that it isn't existing anymore
|
archivecontact Archive a contact when you know that it isn't existing anymore
|
||||||
help Show help about a command, e.g (bin/console help config)
|
help Show help about a command, e.g (bin/console help config)
|
||||||
autoinstall Starts automatic installation of friendica based on values from htconfig.php
|
autoinstall Starts automatic installation of friendica based on values from htconfig.php
|
||||||
|
lock Edit site locks
|
||||||
maintenance Set maintenance mode for this node
|
maintenance Set maintenance mode for this node
|
||||||
newpassword Set a new password for a given user
|
newpassword Set a new password for a given user
|
||||||
php2po Generate a messages.po file from a strings.php file
|
php2po Generate a messages.po file from a strings.php file
|
||||||
|
@ -65,6 +66,7 @@ HELP;
|
||||||
'globalcommunitysilence' => Friendica\Console\GlobalCommunitySilence::class,
|
'globalcommunitysilence' => Friendica\Console\GlobalCommunitySilence::class,
|
||||||
'archivecontact' => Friendica\Console\ArchiveContact::class,
|
'archivecontact' => Friendica\Console\ArchiveContact::class,
|
||||||
'autoinstall' => Friendica\Console\AutomaticInstallation::class,
|
'autoinstall' => Friendica\Console\AutomaticInstallation::class,
|
||||||
|
'lock' => Friendica\Console\Lock::class,
|
||||||
'maintenance' => Friendica\Console\Maintenance::class,
|
'maintenance' => Friendica\Console\Maintenance::class,
|
||||||
'newpassword' => Friendica\Console\NewPassword::class,
|
'newpassword' => Friendica\Console\NewPassword::class,
|
||||||
'php2po' => Friendica\Console\PhpToPo::class,
|
'php2po' => Friendica\Console\PhpToPo::class,
|
||||||
|
|
|
@ -7,6 +7,11 @@ use Friendica\Core\Cache\IMemoryCache;
|
||||||
|
|
||||||
class CacheLock extends Lock
|
class CacheLock extends Lock
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string The static prefix of all locks inside the cache
|
||||||
|
*/
|
||||||
|
const CACHE_PREFIX = 'lock:';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Friendica\Core\Cache\ICache;
|
* @var \Friendica\Core\Cache\ICache;
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +30,7 @@ class CacheLock extends Lock
|
||||||
/**
|
/**
|
||||||
* (@inheritdoc)
|
* (@inheritdoc)
|
||||||
*/
|
*/
|
||||||
public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
|
public function acquireLock($key, $timeout = 120, $ttl = Cache\Cache::FIVE_MINUTES)
|
||||||
{
|
{
|
||||||
$got_lock = false;
|
$got_lock = false;
|
||||||
$start = time();
|
$start = time();
|
||||||
|
@ -85,6 +90,46 @@ class CacheLock extends Lock
|
||||||
return isset($lock) && ($lock !== false);
|
return isset($lock) && ($lock !== false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->cache->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getLocks(string $prefix = '')
|
||||||
|
{
|
||||||
|
$locks = $this->cache->getAllKeys(self::CACHE_PREFIX . $prefix);
|
||||||
|
|
||||||
|
array_walk($locks, function (&$lock, $key) {
|
||||||
|
$lock = substr($lock, strlen(self::CACHE_PREFIX));
|
||||||
|
});
|
||||||
|
|
||||||
|
return $locks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function releaseAll($override = false)
|
||||||
|
{
|
||||||
|
$success = parent::releaseAll($override);
|
||||||
|
|
||||||
|
$locks = $this->getLocks();
|
||||||
|
|
||||||
|
foreach ($locks as $lock) {
|
||||||
|
if (!$this->releaseLock($lock, $override)) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $key The original key
|
* @param string $key The original key
|
||||||
*
|
*
|
||||||
|
@ -92,6 +137,6 @@ class CacheLock extends Lock
|
||||||
*/
|
*/
|
||||||
private static function getLockKey($key)
|
private static function getLockKey($key)
|
||||||
{
|
{
|
||||||
return "lock:" . $key;
|
return self::CACHE_PREFIX . $key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,9 +92,16 @@ class DatabaseLock extends Lock
|
||||||
/**
|
/**
|
||||||
* (@inheritdoc)
|
* (@inheritdoc)
|
||||||
*/
|
*/
|
||||||
public function releaseAll()
|
public function releaseAll($override = false)
|
||||||
{
|
{
|
||||||
$return = $this->dba->delete('locks', ['pid' => $this->pid]);
|
$success = parent::releaseAll($override);
|
||||||
|
|
||||||
|
if ($override) {
|
||||||
|
$where = ['1 = 1'];
|
||||||
|
} else {
|
||||||
|
$where = ['pid' => $this->pid];
|
||||||
|
}
|
||||||
|
$return = $this->dba->delete('locks', $where);
|
||||||
|
|
||||||
$this->acquiredLocks = [];
|
$this->acquiredLocks = [];
|
||||||
|
|
||||||
|
@ -114,4 +121,34 @@ class DatabaseLock extends Lock
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return self::TYPE_DATABASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getLocks(string $prefix = '')
|
||||||
|
{
|
||||||
|
if (empty($prefix)) {
|
||||||
|
$where = ['`expires` >= ?', DateTimeFormat::utcNow()];
|
||||||
|
} else {
|
||||||
|
$where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $this->dba->select('locks', ['name'], $where);
|
||||||
|
|
||||||
|
$keys = [];
|
||||||
|
while ($key = $this->dba->fetch($stmt)) {
|
||||||
|
array_push($keys, $key['name']);
|
||||||
|
}
|
||||||
|
$this->dba->close($stmt);
|
||||||
|
|
||||||
|
return $keys;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,25 @@ interface ILock
|
||||||
/**
|
/**
|
||||||
* Releases all lock that were set by us
|
* Releases all lock that were set by us
|
||||||
*
|
*
|
||||||
|
* @param bool $override Override to release all locks
|
||||||
|
*
|
||||||
* @return boolean Was the unlock of all locks successful?
|
* @return boolean Was the unlock of all locks successful?
|
||||||
*/
|
*/
|
||||||
public function releaseAll();
|
public function releaseAll($override = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the current lock
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all locks
|
||||||
|
*
|
||||||
|
* @param string prefix optional a prefix to search
|
||||||
|
*
|
||||||
|
* @return array Empty if it isn't supported by the cache driver
|
||||||
|
*/
|
||||||
|
public function getLocks(string $prefix = '');
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Friendica\Core\Lock;
|
namespace Friendica\Core\Lock;
|
||||||
|
|
||||||
|
use Friendica\Core\Cache\Cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AbstractLock
|
* Class AbstractLock
|
||||||
*
|
*
|
||||||
|
@ -11,6 +13,9 @@ namespace Friendica\Core\Lock;
|
||||||
*/
|
*/
|
||||||
abstract class Lock implements ILock
|
abstract class Lock implements ILock
|
||||||
{
|
{
|
||||||
|
const TYPE_DATABASE = Cache::TYPE_DATABASE;
|
||||||
|
const TYPE_SEMAPHORE = 'semaphore';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array The local acquired locks
|
* @var array The local acquired locks
|
||||||
*/
|
*/
|
||||||
|
@ -49,16 +54,14 @@ abstract class Lock implements ILock
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases all lock that were set by us
|
* {@inheritDoc}
|
||||||
*
|
|
||||||
* @return boolean Was the unlock of all locks successful?
|
|
||||||
*/
|
*/
|
||||||
public function releaseAll()
|
public function releaseAll($override = false)
|
||||||
{
|
{
|
||||||
$return = true;
|
$return = true;
|
||||||
|
|
||||||
foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
|
foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
|
||||||
if (!$this->releaseLock($acquiredLock)) {
|
if (!$this->releaseLock($acquiredLock, $override)) {
|
||||||
$return = false;
|
$return = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,7 @@ class SemaphoreLock extends Lock
|
||||||
*/
|
*/
|
||||||
private static function semaphoreKey($key)
|
private static function semaphoreKey($key)
|
||||||
{
|
{
|
||||||
$temp = get_temppath();
|
$file = self::keyToFile($key);
|
||||||
|
|
||||||
$file = $temp . '/' . $key . '.sem';
|
|
||||||
|
|
||||||
if (!file_exists($file)) {
|
if (!file_exists($file)) {
|
||||||
file_put_contents($file, $key);
|
file_put_contents($file, $key);
|
||||||
|
@ -31,10 +29,24 @@ class SemaphoreLock extends Lock
|
||||||
return ftok($file, 'f');
|
return ftok($file, 'f');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the full path to the semaphore file
|
||||||
|
*
|
||||||
|
* @param string $key The key of the semaphore
|
||||||
|
*
|
||||||
|
* @return string The full path
|
||||||
|
*/
|
||||||
|
private static function keyToFile($key)
|
||||||
|
{
|
||||||
|
$temp = get_temppath();
|
||||||
|
|
||||||
|
return $temp . '/' . $key . '.sem';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (@inheritdoc)
|
* (@inheritdoc)
|
||||||
*/
|
*/
|
||||||
public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
|
public function acquireLock($key, $timeout = 120, $ttl = Cache\Cache::FIVE_MINUTES)
|
||||||
{
|
{
|
||||||
self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
|
self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
|
||||||
if (self::$semaphore[$key]) {
|
if (self::$semaphore[$key]) {
|
||||||
|
@ -52,14 +64,24 @@ class SemaphoreLock extends Lock
|
||||||
*/
|
*/
|
||||||
public function releaseLock($key, $override = false)
|
public function releaseLock($key, $override = false)
|
||||||
{
|
{
|
||||||
if (empty(self::$semaphore[$key])) {
|
$success = false;
|
||||||
return false;
|
|
||||||
} else {
|
if (!empty(self::$semaphore[$key])) {
|
||||||
$success = @sem_release(self::$semaphore[$key]);
|
try {
|
||||||
unset(self::$semaphore[$key]);
|
$success = @sem_release(self::$semaphore[$key]) &&
|
||||||
$this->markRelease($key);
|
unlink(self::keyToFile($key));
|
||||||
return $success;
|
unset(self::$semaphore[$key]);
|
||||||
|
$this->markRelease($key);
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
} else if ($override) {
|
||||||
|
if ($this->acquireLock($key)) {
|
||||||
|
$success = $this->releaseLock($key, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,4 +91,47 @@ class SemaphoreLock extends Lock
|
||||||
{
|
{
|
||||||
return isset(self::$semaphore[$key]);
|
return isset(self::$semaphore[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return self::TYPE_SEMAPHORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getLocks(string $prefix = '')
|
||||||
|
{
|
||||||
|
$temp = get_temppath();
|
||||||
|
$locks = [];
|
||||||
|
foreach (glob(sprintf('%s/%s*.sem', $temp, $prefix)) as $lock) {
|
||||||
|
$lock = pathinfo($lock, PATHINFO_FILENAME);
|
||||||
|
if(sem_get(self::semaphoreKey($lock))) {
|
||||||
|
$locks[] = $lock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $locks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function releaseAll($override = false)
|
||||||
|
{
|
||||||
|
$success = parent::releaseAll($override);
|
||||||
|
|
||||||
|
$temp = get_temppath();
|
||||||
|
foreach (glob(sprintf('%s/*.sem', $temp)) as $lock) {
|
||||||
|
$lock = pathinfo($lock, PATHINFO_FILENAME);
|
||||||
|
if (!$this->releaseLock($lock, true)) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,12 @@ abstract class LockTest extends MockedTest
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->instance = $this->getInstance();
|
$this->instance = $this->getInstance();
|
||||||
$this->instance->releaseAll();
|
$this->instance->releaseAll(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown()
|
protected function tearDown()
|
||||||
{
|
{
|
||||||
$this->instance->releaseAll();
|
$this->instance->releaseAll(true);
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +123,46 @@ abstract class LockTest extends MockedTest
|
||||||
$this->assertFalse($this->instance->isLocked('test'));
|
$this->assertFalse($this->instance->isLocked('test'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @small
|
||||||
|
*/
|
||||||
|
public function testGetLocks()
|
||||||
|
{
|
||||||
|
$this->assertTrue($this->instance->acquireLock('foo', 1));
|
||||||
|
$this->assertTrue($this->instance->acquireLock('bar', 1));
|
||||||
|
$this->assertTrue($this->instance->acquireLock('nice', 1));
|
||||||
|
|
||||||
|
$this->assertTrue($this->instance->isLocked('foo'));
|
||||||
|
$this->assertTrue($this->instance->isLocked('bar'));
|
||||||
|
$this->assertTrue($this->instance->isLocked('nice'));
|
||||||
|
|
||||||
|
$locks = $this->instance->getLocks();
|
||||||
|
|
||||||
|
$this->assertContains('foo', $locks);
|
||||||
|
$this->assertContains('bar', $locks);
|
||||||
|
$this->assertContains('nice', $locks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @small
|
||||||
|
*/
|
||||||
|
public function testGetLocksWithPrefix()
|
||||||
|
{
|
||||||
|
$this->assertTrue($this->instance->acquireLock('foo', 1));
|
||||||
|
$this->assertTrue($this->instance->acquireLock('test1', 1));
|
||||||
|
$this->assertTrue($this->instance->acquireLock('test2', 1));
|
||||||
|
|
||||||
|
$this->assertTrue($this->instance->isLocked('foo'));
|
||||||
|
$this->assertTrue($this->instance->isLocked('test1'));
|
||||||
|
$this->assertTrue($this->instance->isLocked('test2'));
|
||||||
|
|
||||||
|
$locks = $this->instance->getLocks('test');
|
||||||
|
|
||||||
|
$this->assertContains('test1', $locks);
|
||||||
|
$this->assertContains('test2', $locks);
|
||||||
|
$this->assertNotContains('foo', $locks);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @medium
|
* @medium
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -12,8 +12,6 @@ class SemaphoreLockTest extends LockTest
|
||||||
{
|
{
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
$dice = \Mockery::mock(Dice::class)->makePartial();
|
$dice = \Mockery::mock(Dice::class)->makePartial();
|
||||||
|
|
||||||
$app = \Mockery::mock(App::class);
|
$app = \Mockery::mock(App::class);
|
||||||
|
@ -29,6 +27,8 @@ class SemaphoreLockTest extends LockTest
|
||||||
|
|
||||||
// @todo Because "get_temppath()" is using static methods, we have to initialize the BaseObject
|
// @todo Because "get_temppath()" is using static methods, we have to initialize the BaseObject
|
||||||
BaseObject::setDependencyInjection($dice);
|
BaseObject::setDependencyInjection($dice);
|
||||||
|
|
||||||
|
parent::setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getInstance()
|
protected function getInstance()
|
||||||
|
|
Loading…
Reference in a new issue