Merge pull request #1570 from ArthurHoaro/feature/datastore-mutex

Add mutex on datastore I/O operations
This commit is contained in:
ArthurHoaro 2020-10-13 13:30:37 +02:00 committed by GitHub
commit 29c31b7ec6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 218 additions and 63 deletions

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Shaarli\Api; namespace Shaarli\Api;
use malkusch\lock\mutex\FlockMutex;
use Shaarli\Api\Exceptions\ApiAuthorizationException; use Shaarli\Api\Exceptions\ApiAuthorizationException;
use Shaarli\Api\Exceptions\ApiException; use Shaarli\Api\Exceptions\ApiException;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
@ -143,6 +144,7 @@ protected function setLinkDb($conf)
$linkDb = new BookmarkFileService( $linkDb = new BookmarkFileService(
$conf, $conf,
$this->container->get('history'), $this->container->get('history'),
new FlockMutex(fopen(SHAARLI_MUTEX_FILE, 'r'), 2),
true true
); );
$this->container['db'] = $linkDb; $this->container['db'] = $linkDb;

View file

@ -5,6 +5,7 @@
use Exception; use Exception;
use malkusch\lock\mutex\Mutex;
use Shaarli\Bookmark\Exception\BookmarkNotFoundException; use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Bookmark\Exception\DatastoreNotInitializedException; use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
use Shaarli\Bookmark\Exception\EmptyDataStoreException; use Shaarli\Bookmark\Exception\EmptyDataStoreException;
@ -47,15 +48,19 @@ class BookmarkFileService implements BookmarkServiceInterface
/** @var bool true for logged in users. Default value to retrieve private bookmarks. */ /** @var bool true for logged in users. Default value to retrieve private bookmarks. */
protected $isLoggedIn; protected $isLoggedIn;
/** @var Mutex */
protected $mutex;
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function __construct(ConfigManager $conf, History $history, $isLoggedIn) public function __construct(ConfigManager $conf, History $history, Mutex $mutex, $isLoggedIn)
{ {
$this->conf = $conf; $this->conf = $conf;
$this->history = $history; $this->history = $history;
$this->mutex = $mutex;
$this->pageCacheManager = new PageCacheManager($this->conf->get('resource.page_cache'), $isLoggedIn); $this->pageCacheManager = new PageCacheManager($this->conf->get('resource.page_cache'), $isLoggedIn);
$this->bookmarksIO = new BookmarkIO($this->conf); $this->bookmarksIO = new BookmarkIO($this->conf, $this->mutex);
$this->isLoggedIn = $isLoggedIn; $this->isLoggedIn = $isLoggedIn;
if (!$this->isLoggedIn && $this->conf->get('privacy.hide_public_links', false)) { if (!$this->isLoggedIn && $this->conf->get('privacy.hide_public_links', false)) {

View file

@ -2,6 +2,8 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use malkusch\lock\mutex\Mutex;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\Exception\DatastoreNotInitializedException; use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
use Shaarli\Bookmark\Exception\EmptyDataStoreException; use Shaarli\Bookmark\Exception\EmptyDataStoreException;
use Shaarli\Bookmark\Exception\NotWritableDataStoreException; use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
@ -27,11 +29,14 @@ class BookmarkIO
*/ */
protected $conf; protected $conf;
/** @var Mutex */
protected $mutex;
/** /**
* string Datastore PHP prefix * string Datastore PHP prefix
*/ */
protected static $phpPrefix = '<?php /* '; protected static $phpPrefix = '<?php /* ';
/** /**
* string Datastore PHP suffix * string Datastore PHP suffix
*/ */
@ -42,10 +47,15 @@ class BookmarkIO
* *
* @param ConfigManager $conf instance * @param ConfigManager $conf instance
*/ */
public function __construct($conf) public function __construct(ConfigManager $conf, Mutex $mutex = null)
{ {
if ($mutex === null) {
// This should only happen with legacy classes
$mutex = new NoMutex();
}
$this->conf = $conf; $this->conf = $conf;
$this->datastore = $conf->get('resource.datastore'); $this->datastore = $conf->get('resource.datastore');
$this->mutex = $mutex;
} }
/** /**
@ -67,11 +77,16 @@ public function read()
throw new NotWritableDataStoreException($this->datastore); throw new NotWritableDataStoreException($this->datastore);
} }
$content = null;
$this->mutex->synchronized(function () use (&$content) {
$content = file_get_contents($this->datastore);
});
// Note that gzinflate is faster than gzuncompress. // Note that gzinflate is faster than gzuncompress.
// See: http://www.php.net/manual/en/function.gzdeflate.php#96439 // See: http://www.php.net/manual/en/function.gzdeflate.php#96439
$links = unserialize(gzinflate(base64_decode( $links = unserialize(gzinflate(base64_decode(
substr(file_get_contents($this->datastore), substr($content, strlen(self::$phpPrefix), -strlen(self::$phpSuffix))
strlen(self::$phpPrefix), -strlen(self::$phpSuffix))))); )));
if (empty($links)) { if (empty($links)) {
if (filesize($this->datastore) > 100) { if (filesize($this->datastore) > 100) {
@ -100,9 +115,13 @@ public function write($links)
throw new NotWritableDataStoreException(dirname($this->datastore)); throw new NotWritableDataStoreException(dirname($this->datastore));
} }
file_put_contents( $data = self::$phpPrefix.base64_encode(gzdeflate(serialize($links))).self::$phpSuffix;
$this->datastore,
self::$phpPrefix.base64_encode(gzdeflate(serialize($links))).self::$phpSuffix $this->mutex->synchronized(function () use ($data) {
); file_put_contents(
$this->datastore,
$data
);
});
} }
} }

View file

@ -5,8 +5,6 @@
use Shaarli\Bookmark\Exception\BookmarkNotFoundException; use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Bookmark\Exception\NotWritableDataStoreException; use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
use Shaarli\Config\ConfigManager;
use Shaarli\History;
/** /**
* Class BookmarksService * Class BookmarksService
@ -15,15 +13,6 @@
*/ */
interface BookmarkServiceInterface interface BookmarkServiceInterface
{ {
/**
* BookmarksService constructor.
*
* @param ConfigManager $conf instance
* @param History $history instance
* @param bool $isLoggedIn true if the current user is logged in
*/
public function __construct(ConfigManager $conf, History $history, $isLoggedIn);
/** /**
* Find a bookmark by hash * Find a bookmark by hash
* *

View file

@ -4,6 +4,7 @@
namespace Shaarli\Container; namespace Shaarli\Container;
use malkusch\lock\mutex\FlockMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\BookmarkServiceInterface; use Shaarli\Bookmark\BookmarkServiceInterface;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -84,6 +85,7 @@ public function build(): ShaarliContainer
return new BookmarkFileService( return new BookmarkFileService(
$container->conf, $container->conf,
$container->history, $container->history,
new FlockMutex(fopen(SHAARLI_MUTEX_FILE, 'r'), 2),
$container->loginManager->isLoggedIn() $container->loginManager->isLoggedIn()
); );
}; };

View file

@ -23,6 +23,7 @@
"erusev/parsedown": "^1.6", "erusev/parsedown": "^1.6",
"erusev/parsedown-extra": "^0.8.1", "erusev/parsedown-extra": "^0.8.1",
"gettext/gettext": "^4.4", "gettext/gettext": "^4.4",
"malkusch/lock": "^2.1",
"pubsubhubbub/publisher": "dev-master", "pubsubhubbub/publisher": "dev-master",
"shaarli/netscape-bookmark-parser": "^2.1", "shaarli/netscape-bookmark-parser": "^2.1",
"slim/slim": "^3.0" "slim/slim": "^3.0"

87
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f84918821b0dceb0cd569875c0418bb8", "content-hash": "932b191006135ff8be495aa0b4ba7e09",
"packages": [ "packages": [
{ {
"name": "arthurhoaro/web-thumbnailer", "name": "arthurhoaro/web-thumbnailer",
@ -344,6 +344,91 @@
}, },
"time": "2016-11-07T19:29:14+00:00" "time": "2016-11-07T19:29:14+00:00"
}, },
{
"name": "malkusch/lock",
"version": "v2.1",
"source": {
"type": "git",
"url": "https://github.com/php-lock/lock.git",
"reference": "093f389ec2f38fc8686d2f70e23378182fce7714"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-lock/lock/zipball/093f389ec2f38fc8686d2f70e23378182fce7714",
"reference": "093f389ec2f38fc8686d2f70e23378182fce7714",
"shasum": ""
},
"require": {
"php": ">=7.1",
"psr/log": "^1"
},
"require-dev": {
"eloquent/liberator": "^2.0",
"ext-memcached": "*",
"ext-pcntl": "*",
"ext-pdo_mysql": "*",
"ext-pdo_sqlite": "*",
"ext-redis": "*",
"ext-sysvsem": "*",
"johnkary/phpunit-speedtrap": "^3.0",
"kriswallsmith/spork": "^0.3",
"mikey179/vfsstream": "^1.6",
"php-mock/php-mock-phpunit": "^2.1",
"phpunit/phpunit": "^7.4",
"predis/predis": "^1.1",
"squizlabs/php_codesniffer": "^3.3"
},
"suggest": {
"ext-pnctl": "Enables locking with flock without busy waiting in CLI scripts.",
"ext-redis": "To use this library with the PHP Redis extension.",
"ext-sysvsem": "Enables locking using semaphores.",
"predis/predis": "To use this library with predis."
},
"type": "library",
"autoload": {
"psr-4": {
"malkusch\\lock\\": "classes/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"WTFPL"
],
"authors": [
{
"name": "Markus Malkusch",
"email": "markus@malkusch.de",
"homepage": "http://markus.malkusch.de",
"role": "Developer"
},
{
"name": "Willem Stuursma-Ruwen",
"email": "willem@stuursma.name",
"role": "Developer"
}
],
"description": "Mutex library for exclusive code execution.",
"homepage": "https://github.com/malkusch/lock",
"keywords": [
"advisory-locks",
"cas",
"flock",
"lock",
"locking",
"memcache",
"mutex",
"mysql",
"postgresql",
"redis",
"redlock",
"semaphore"
],
"support": {
"issues": "https://github.com/php-lock/lock/issues",
"source": "https://github.com/php-lock/lock/tree/v2.1"
},
"time": "2018-12-12T19:53:29+00:00"
},
{ {
"name": "nikic/fast-route", "name": "nikic/fast-route",
"version": "v1.3.0", "version": "v1.3.0",

View file

@ -60,6 +60,7 @@
ini_set('session.use_trans_sid', false); ini_set('session.use_trans_sid', false);
define('SHAARLI_VERSION', ApplicationUtils::getVersion(__DIR__ .'/'. ApplicationUtils::$VERSION_FILE)); define('SHAARLI_VERSION', ApplicationUtils::getVersion(__DIR__ .'/'. ApplicationUtils::$VERSION_FILE));
define('SHAARLI_MUTEX_FILE', __FILE__);
session_name('shaarli'); session_name('shaarli');
// Start session if needed (Some server auto-start sessions). // Start session if needed (Some server auto-start sessions).

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
@ -49,6 +50,7 @@ class InfoTest extends TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -58,7 +60,7 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, true); $this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Info($this->container); $this->controller = new Info($this->container);

View file

@ -3,6 +3,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
@ -53,11 +54,15 @@ class DeleteLinkTest extends \Shaarli\TestCase
*/ */
protected $controller; protected $controller;
/** @var NoMutex */
protected $mutex;
/** /**
* Before each test, instantiate a new Api with its config, plugins and bookmarks. * Before each test, instantiate a new Api with its config, plugins and bookmarks.
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$this->mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -65,7 +70,7 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
@ -100,7 +105,7 @@ public function testDeleteLinkValid()
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(204, $response->getStatusCode());
$this->assertEmpty((string) $response->getBody()); $this->assertEmpty((string) $response->getBody());
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->assertFalse($this->bookmarkService->exists($id)); $this->assertFalse($this->bookmarkService->exists($id));
$historyEntry = $this->history->getHistory()[0]; $historyEntry = $this->history->getHistory()[0];

View file

@ -2,6 +2,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\Bookmark;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -57,6 +58,7 @@ class GetLinkIdTest extends \Shaarli\TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -65,7 +67,7 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, true); $this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Links($this->container); $this->controller = new Links($this->container);

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\Bookmark;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
@ -57,6 +58,7 @@ class GetLinksTest extends \Shaarli\TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -65,7 +67,7 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, true); $this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Links($this->container); $this->controller = new Links($this->container);

View file

@ -2,6 +2,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\Bookmark;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -72,6 +73,7 @@ class PostLinkTest extends TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -79,7 +81,7 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;

View file

@ -3,6 +3,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\Bookmark;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -64,6 +65,7 @@ class PutLinkTest extends \Shaarli\TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -71,7 +73,7 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;

View file

@ -3,6 +3,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -54,11 +55,15 @@ class DeleteTagTest extends \Shaarli\TestCase
*/ */
protected $controller; protected $controller;
/** @var NoMutex */
protected $mutex;
/** /**
* Before each test, instantiate a new Api with its config, plugins and bookmarks. * Before each test, instantiate a new Api with its config, plugins and bookmarks.
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$this->mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -66,7 +71,7 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
@ -102,7 +107,7 @@ public function testDeleteTagValid()
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(204, $response->getStatusCode());
$this->assertEmpty((string) $response->getBody()); $this->assertEmpty((string) $response->getBody());
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$tags = $this->bookmarkService->bookmarksCountPerTag(); $tags = $this->bookmarkService->bookmarksCountPerTag();
$this->assertFalse(isset($tags[$tagName])); $this->assertFalse(isset($tags[$tagName]));
@ -136,7 +141,7 @@ public function testDeleteTagCaseSensitivity()
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(204, $response->getStatusCode());
$this->assertEmpty((string) $response->getBody()); $this->assertEmpty((string) $response->getBody());
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$tags = $this->bookmarkService->bookmarksCountPerTag(); $tags = $this->bookmarkService->bookmarksCountPerTag();
$this->assertFalse(isset($tags[$tagName])); $this->assertFalse(isset($tags[$tagName]));
$this->assertTrue($tags[strtolower($tagName)] > 0); $this->assertTrue($tags[strtolower($tagName)] > 0);

View file

@ -2,6 +2,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -55,6 +56,7 @@ class GetTagNameTest extends \Shaarli\TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -63,7 +65,7 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, true); $this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Tags($this->container); $this->controller = new Tags($this->container);

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -59,13 +60,14 @@ class GetTagsTest extends \Shaarli\TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
$this->refDB->write(self::$testDatastore); $this->refDB->write(self::$testDatastore);
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
$this->bookmarkService = new BookmarkFileService($this->conf, $history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $history, $mutex, true);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;

View file

@ -2,6 +2,7 @@
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Api\Exceptions\ApiBadParametersException; use Shaarli\Api\Exceptions\ApiBadParametersException;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
@ -64,6 +65,7 @@ class PutTagTest extends \Shaarli\TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->conf = new ConfigManager('tests/utils/config/configJson'); $this->conf = new ConfigManager('tests/utils/config/configJson');
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
@ -71,7 +73,7 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;

View file

@ -6,6 +6,7 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use DateTime; use DateTime;
use malkusch\lock\mutex\NoMutex;
use ReferenceLinkDB; use ReferenceLinkDB;
use ReflectionClass; use ReflectionClass;
use Shaarli; use Shaarli;
@ -52,6 +53,9 @@ class BookmarkFileServiceTest extends TestCase
*/ */
protected $privateLinkDB = null; protected $privateLinkDB = null;
/** @var NoMutex */
protected $mutex;
/** /**
* Instantiates public and private LinkDBs with test data * Instantiates public and private LinkDBs with test data
* *
@ -68,6 +72,8 @@ class BookmarkFileServiceTest extends TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$this->mutex = new NoMutex();
if (file_exists(self::$testDatastore)) { if (file_exists(self::$testDatastore)) {
unlink(self::$testDatastore); unlink(self::$testDatastore);
} }
@ -87,8 +93,8 @@ protected function setUp(): void
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
$this->refDB->write(self::$testDatastore); $this->refDB->write(self::$testDatastore);
$this->history = new History('sandbox/history.php'); $this->history = new History('sandbox/history.php');
$this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, false); $this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false);
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
} }
/** /**
@ -105,7 +111,7 @@ public function testDatabaseMigration()
$db = self::getMethod('migrate'); $db = self::getMethod('migrate');
$db->invokeArgs($this->privateLinkDB, []); $db->invokeArgs($this->privateLinkDB, []);
$db = new \FakeBookmarkService($this->conf, $this->history, true); $db = new \FakeBookmarkService($this->conf, $this->history, $this->mutex, true);
$this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
$this->assertEquals($this->refDB->countLinks(), $db->count()); $this->assertEquals($this->refDB->countLinks(), $db->count());
} }
@ -174,7 +180,7 @@ public function testAddFull()
$this->assertEquals($updated, $bookmark->getUpdated()); $this->assertEquals($updated, $bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(43); $bookmark = $this->privateLinkDB->get(43);
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
@ -212,7 +218,7 @@ public function testAddMinimal()
$this->assertNull($bookmark->getUpdated()); $this->assertNull($bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(43); $bookmark = $this->privateLinkDB->get(43);
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
@ -242,7 +248,7 @@ public function testAddMinimalNoWrite()
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->privateLinkDB->get(43); $this->privateLinkDB->get(43);
} }
@ -314,7 +320,7 @@ public function testSetFull()
$this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -355,7 +361,7 @@ public function testSetMinimal()
$this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -388,7 +394,7 @@ public function testSetMinimalNoWrite()
$this->assertEquals($title, $bookmark->getTitle()); $this->assertEquals($title, $bookmark->getTitle());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -452,7 +458,7 @@ public function testAddOrSetNew()
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(43); $bookmark = $this->privateLinkDB->get(43);
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
@ -472,7 +478,7 @@ public function testAddOrSetExisting()
$this->assertEquals($title, $bookmark->getTitle()); $this->assertEquals($title, $bookmark->getTitle());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -515,7 +521,7 @@ public function testAddOrSetMinimalNoWrite()
$this->assertEquals($title, $bookmark->getTitle()); $this->assertEquals($title, $bookmark->getTitle());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -541,7 +547,7 @@ public function testRemoveExisting()
$this->assertInstanceOf(BookmarkNotFoundException::class, $exception); $this->assertInstanceOf(BookmarkNotFoundException::class, $exception);
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->privateLinkDB->get(42); $this->privateLinkDB->get(42);
} }
@ -645,7 +651,7 @@ public function testConstructDatastoreNotWriteable()
$conf = new ConfigManager('tests/utils/config/configJson'); $conf = new ConfigManager('tests/utils/config/configJson');
$conf->set('resource.datastore', 'null/store.db'); $conf->set('resource.datastore', 'null/store.db');
new BookmarkFileService($conf, $this->history, true); new BookmarkFileService($conf, $this->history, $this->mutex, true);
} }
/** /**
@ -655,7 +661,7 @@ public function testCheckDBNewLoggedIn()
{ {
unlink(self::$testDatastore); unlink(self::$testDatastore);
$this->assertFileNotExists(self::$testDatastore); $this->assertFileNotExists(self::$testDatastore);
new BookmarkFileService($this->conf, $this->history, true); new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->assertFileExists(self::$testDatastore); $this->assertFileExists(self::$testDatastore);
// ensure the correct data has been written // ensure the correct data has been written
@ -669,7 +675,7 @@ public function testCheckDBNewLoggedOut()
{ {
unlink(self::$testDatastore); unlink(self::$testDatastore);
$this->assertFileNotExists(self::$testDatastore); $this->assertFileNotExists(self::$testDatastore);
$db = new \FakeBookmarkService($this->conf, $this->history, false); $db = new \FakeBookmarkService($this->conf, $this->history, $this->mutex, false);
$this->assertFileNotExists(self::$testDatastore); $this->assertFileNotExists(self::$testDatastore);
$this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
$this->assertCount(0, $db->getBookmarks()); $this->assertCount(0, $db->getBookmarks());
@ -702,13 +708,13 @@ public function testReadPrivateDB()
*/ */
public function testSave() public function testSave()
{ {
$testDB = new BookmarkFileService($this->conf, $this->history, true); $testDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$dbSize = $testDB->count(); $dbSize = $testDB->count();
$bookmark = new Bookmark(); $bookmark = new Bookmark();
$testDB->add($bookmark); $testDB->add($bookmark);
$testDB = new BookmarkFileService($this->conf, $this->history, true); $testDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->assertEquals($dbSize + 1, $testDB->count()); $this->assertEquals($dbSize + 1, $testDB->count());
} }
@ -718,7 +724,7 @@ public function testSave()
public function testCountHiddenPublic() public function testCountHiddenPublic()
{ {
$this->conf->set('privacy.hide_public_links', true); $this->conf->set('privacy.hide_public_links', true);
$linkDB = new BookmarkFileService($this->conf, $this->history, false); $linkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false);
$this->assertEquals(0, $linkDB->count()); $this->assertEquals(0, $linkDB->count());
} }

View file

@ -3,6 +3,7 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use Exception; use Exception;
use malkusch\lock\mutex\NoMutex;
use ReferenceLinkDB; use ReferenceLinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
@ -37,12 +38,13 @@ class BookmarkFilterTest extends TestCase
*/ */
public static function setUpBeforeClass(): void public static function setUpBeforeClass(): void
{ {
$mutex = new NoMutex();
$conf = new ConfigManager('tests/utils/config/configJson'); $conf = new ConfigManager('tests/utils/config/configJson');
$conf->set('resource.datastore', self::$testDatastore); $conf->set('resource.datastore', self::$testDatastore);
self::$refDB = new \ReferenceLinkDB(); self::$refDB = new \ReferenceLinkDB();
self::$refDB->write(self::$testDatastore); self::$refDB->write(self::$testDatastore);
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
self::$bookmarkService = new \FakeBookmarkService($conf, $history, true); self::$bookmarkService = new \FakeBookmarkService($conf, $history, $mutex, true);
self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks()); self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks());
} }

View file

@ -2,6 +2,7 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\TestCase; use Shaarli\TestCase;
@ -34,11 +35,15 @@ class BookmarkInitializerTest extends TestCase
/** @var BookmarkInitializer instance */ /** @var BookmarkInitializer instance */
protected $initializer; protected $initializer;
/** @var NoMutex */
protected $mutex;
/** /**
* Initialize an empty BookmarkFileService * Initialize an empty BookmarkFileService
*/ */
public function setUp(): void public function setUp(): void
{ {
$this->mutex = new NoMutex();
if (file_exists(self::$testDatastore)) { if (file_exists(self::$testDatastore)) {
unlink(self::$testDatastore); unlink(self::$testDatastore);
} }
@ -47,7 +52,7 @@ public function setUp(): void
$this->conf = new ConfigManager(self::$testConf); $this->conf = new ConfigManager(self::$testConf);
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->history = new History('sandbox/history.php'); $this->history = new History('sandbox/history.php');
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->initializer = new BookmarkInitializer($this->bookmarkService); $this->initializer = new BookmarkInitializer($this->bookmarkService);
} }
@ -59,7 +64,7 @@ public function testInitializeNotEmptyDataStore(): void
{ {
$refDB = new \ReferenceLinkDB(); $refDB = new \ReferenceLinkDB();
$refDB->write(self::$testDatastore); $refDB->write(self::$testDatastore);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->initializer = new BookmarkInitializer($this->bookmarkService); $this->initializer = new BookmarkInitializer($this->bookmarkService);
$this->initializer->initialize(); $this->initializer->initialize();
@ -90,7 +95,7 @@ public function testInitializeNotEmptyDataStore(): void
$this->bookmarkService->save(); $this->bookmarkService->save();
// Reload from file // Reload from file
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count()); $this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count());
$bookmark = $this->bookmarkService->get(43); $bookmark = $this->bookmarkService->get(43);
@ -121,7 +126,7 @@ public function testInitializeNotEmptyDataStore(): void
public function testInitializeNonExistentDataStore(): void public function testInitializeNonExistentDataStore(): void
{ {
$this->conf->set('resource.datastore', static::$testDatastore . '_empty'); $this->conf->set('resource.datastore', static::$testDatastore . '_empty');
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true);
$this->initializer->initialize(); $this->initializer->initialize();

View file

@ -30,3 +30,7 @@ function is_iterable($var)
require_once 'tests/utils/ReferenceSessionIdHashes.php'; require_once 'tests/utils/ReferenceSessionIdHashes.php';
\ReferenceSessionIdHashes::genAllHashes(); \ReferenceSessionIdHashes::genAllHashes();
if (!defined('SHAARLI_MUTEX_FILE')) {
define('SHAARLI_MUTEX_FILE', __FILE__);
}

View file

@ -3,6 +3,7 @@
namespace Shaarli\Feed; namespace Shaarli\Feed;
use DateTime; use DateTime;
use malkusch\lock\mutex\NoMutex;
use ReferenceLinkDB; use ReferenceLinkDB;
use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\Bookmark;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
@ -47,6 +48,7 @@ class FeedBuilderTest extends TestCase
*/ */
public static function setUpBeforeClass(): void public static function setUpBeforeClass(): void
{ {
$mutex = new NoMutex();
$conf = new ConfigManager('tests/utils/config/configJson'); $conf = new ConfigManager('tests/utils/config/configJson');
$conf->set('resource.datastore', self::$testDatastore); $conf->set('resource.datastore', self::$testDatastore);
$refLinkDB = new \ReferenceLinkDB(); $refLinkDB = new \ReferenceLinkDB();
@ -54,7 +56,7 @@ public static function setUpBeforeClass(): void
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
$factory = new FormatterFactory($conf, true); $factory = new FormatterFactory($conf, true);
self::$formatter = $factory->getFormatter(); self::$formatter = $factory->getFormatter();
self::$bookmarkService = new BookmarkFileService($conf, $history, true); self::$bookmarkService = new BookmarkFileService($conf, $history, $mutex, true);
self::$serverInfo = array( self::$serverInfo = array(
'HTTPS' => 'Off', 'HTTPS' => 'Off',

View file

@ -2,6 +2,7 @@
namespace Shaarli\Netscape; namespace Shaarli\Netscape;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Formatter\BookmarkFormatter; use Shaarli\Formatter\BookmarkFormatter;
@ -56,12 +57,13 @@ class BookmarkExportTest extends TestCase
*/ */
public static function setUpBeforeClass(): void public static function setUpBeforeClass(): void
{ {
$mutex = new NoMutex();
static::$conf = new ConfigManager('tests/utils/config/configJson'); static::$conf = new ConfigManager('tests/utils/config/configJson');
static::$conf->set('resource.datastore', static::$testDatastore); static::$conf->set('resource.datastore', static::$testDatastore);
static::$refDb = new \ReferenceLinkDB(); static::$refDb = new \ReferenceLinkDB();
static::$refDb->write(static::$testDatastore); static::$refDb->write(static::$testDatastore);
static::$history = new History('sandbox/history.php'); static::$history = new History('sandbox/history.php');
static::$bookmarkService = new BookmarkFileService(static::$conf, static::$history, true); static::$bookmarkService = new BookmarkFileService(static::$conf, static::$history, $mutex, true);
$factory = new FormatterFactory(static::$conf, true); $factory = new FormatterFactory(static::$conf, true);
static::$formatter = $factory->getFormatter('raw'); static::$formatter = $factory->getFormatter('raw');
} }

View file

@ -3,6 +3,7 @@
namespace Shaarli\Netscape; namespace Shaarli\Netscape;
use DateTime; use DateTime;
use malkusch\lock\mutex\NoMutex;
use Psr\Http\Message\UploadedFileInterface; use Psr\Http\Message\UploadedFileInterface;
use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\Bookmark;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
@ -87,6 +88,7 @@ public static function setUpBeforeClass(): void
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
if (file_exists(self::$testDatastore)) { if (file_exists(self::$testDatastore)) {
unlink(self::$testDatastore); unlink(self::$testDatastore);
} }
@ -97,7 +99,7 @@ protected function setUp(): void
$this->conf->set('resource.page_cache', $this->pagecache); $this->conf->set('resource.page_cache', $this->pagecache);
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->history = new History(self::$historyFilePath); $this->history = new History(self::$historyFilePath);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true);
$this->netscapeBookmarkUtils = new NetscapeBookmarkUtils($this->bookmarkService, $this->conf, $this->history); $this->netscapeBookmarkUtils = new NetscapeBookmarkUtils($this->bookmarkService, $this->conf, $this->history);
} }

View file

@ -2,6 +2,7 @@
namespace Shaarli\Updater; namespace Shaarli\Updater;
use Exception; use Exception;
use malkusch\lock\mutex\NoMutex;
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Bookmark\BookmarkServiceInterface; use Shaarli\Bookmark\BookmarkServiceInterface;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -44,12 +45,13 @@ class UpdaterTest extends TestCase
*/ */
protected function setUp(): void protected function setUp(): void
{ {
$mutex = new NoMutex();
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
$this->refDB->write(self::$testDatastore); $this->refDB->write(self::$testDatastore);
copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php'); copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php');
$this->conf = new ConfigManager(self::$configFile); $this->conf = new ConfigManager(self::$configFile);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->createMock(History::class), true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->createMock(History::class), $mutex, true);
$this->updater = new Updater([], $this->bookmarkService, $this->conf, true); $this->updater = new Updater([], $this->bookmarkService, $this->conf, true);
} }