<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
namespace Friendica\Test\src\Core\Lock;
-use Friendica\App;
-use Friendica\Core\Config;
-use Friendica\Test\DatabaseTest;
-use PHPUnit\Framework\TestCase;
+use Friendica\Core\Lock\ILock;
+use Friendica\Test\MockedTest;
-abstract class LockTest extends DatabaseTest
+abstract class LockTest extends MockedTest
{
/**
- * @var \Friendica\Core\Lock\ILockDriver
+ * @var int Start time of the mock (used for time operations)
+ */
+ protected $startTime = 1417011228;
+
+ /**
+ * @var ILock
*/
protected $instance;
abstract protected function getInstance();
- protected function setUp()
+ protected function setUp(): void
{
- global $a;
parent::setUp();
- $this->instance = $this->getInstance();
- // Reusable App object
- $this->app = \Friendica\BaseObject::getApp();
- $a = $this->app;
+ $this->instance = $this->getInstance();
+ $this->instance->releaseAll(true);
+ }
- // Default config
- Config::set('config', 'hostname', 'localhost');
- Config::set('system', 'throttle_limit_day', 100);
- Config::set('system', 'throttle_limit_week', 100);
- Config::set('system', 'throttle_limit_month', 100);
- Config::set('system', 'theme', 'system_theme');
+ protected function tearDown(): void
+ {
+ $this->instance->releaseAll(true);
+ parent::tearDown();
}
- public function testLock() {
- $this->instance->acquireLock('foo', 1);
- $this->assertTrue($this->instance->isLocked('foo'));
- $this->assertFalse($this->instance->isLocked('bar'));
+ /**
+ * @small
+ */
+ public function testLock()
+ {
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->isLocked('foo'));
+ self::assertFalse($this->instance->isLocked('bar'));
}
- public function testDoubleLock() {
- $this->instance->acquireLock('foo', 1);
- $this->assertTrue($this->instance->isLocked('foo'));
+ /**
+ * @small
+ */
+ public function testDoubleLock()
+ {
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->isLocked('foo'));
// We already locked it
- $this->assertTrue($this->instance->acquireLock('foo', 1));
+ self::assertTrue($this->instance->acquire('foo', 1));
}
- public function testReleaseLock() {
- $this->instance->acquireLock('foo', 1);
- $this->assertTrue($this->instance->isLocked('foo'));
- $this->instance->releaseLock('foo');
- $this->assertFalse($this->instance->isLocked('foo'));
+ /**
+ * @small
+ */
+ public function testReleaseLock()
+ {
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->isLocked('foo'));
+ $this->instance->release('foo');
+ self::assertFalse($this->instance->isLocked('foo'));
}
- public function testReleaseAll() {
- $this->instance->acquireLock('foo', 1);
- $this->instance->acquireLock('bar', 1);
- $this->instance->acquireLock('nice', 1);
+ /**
+ * @small
+ */
+ public function testReleaseAll()
+ {
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->acquire('bar', 1));
+ self::assertTrue($this->instance->acquire('nice', 1));
+
+ self::assertTrue($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->isLocked('bar'));
+ self::assertTrue($this->instance->isLocked('nice'));
+
+ self::assertTrue($this->instance->releaseAll());
+
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertFalse($this->instance->isLocked('bar'));
+ self::assertFalse($this->instance->isLocked('nice'));
+ }
+
+ /**
+ * @small
+ */
+ public function testReleaseAfterUnlock()
+ {
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertFalse($this->instance->isLocked('bar'));
+ self::assertFalse($this->instance->isLocked('nice'));
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->acquire('bar', 1));
+ self::assertTrue($this->instance->acquire('nice', 1));
+
+ self::assertTrue($this->instance->release('foo'));
- $this->assertTrue($this->instance->isLocked('foo'));
- $this->assertTrue($this->instance->isLocked('bar'));
- $this->assertTrue($this->instance->isLocked('nice'));
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->isLocked('bar'));
+ self::assertTrue($this->instance->isLocked('nice'));
- $this->instance->releaseAll();
+ self::assertTrue($this->instance->releaseAll());
+
+ self::assertFalse($this->instance->isLocked('bar'));
+ self::assertFalse($this->instance->isLocked('nice'));
+ }
- $this->assertFalse($this->instance->isLocked('foo'));
- $this->assertFalse($this->instance->isLocked('bar'));
- $this->assertFalse($this->instance->isLocked('nice'));
+ /**
+ * @small
+ */
+ public function testReleaseWitTTL()
+ {
+ self::assertFalse($this->instance->isLocked('test'));
+ self::assertTrue($this->instance->acquire('test', 1, 10));
+ self::assertTrue($this->instance->isLocked('test'));
+ self::assertTrue($this->instance->release('test'));
+ self::assertFalse($this->instance->isLocked('test'));
}
- public function testReleaseAfterUnlock() {
- $this->instance->acquireLock('foo', 1);
- $this->instance->acquireLock('bar', 1);
- $this->instance->acquireLock('nice', 1);
+ /**
+ * @small
+ */
+ public function testGetLocks()
+ {
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->acquire('bar', 1));
+ self::assertTrue($this->instance->acquire('nice', 1));
+
+ self::assertTrue($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->isLocked('bar'));
+ self::assertTrue($this->instance->isLocked('nice'));
+
+ $locks = $this->instance->getLocks();
+
+ self::assertContains('foo', $locks);
+ self::assertContains('bar', $locks);
+ self::assertContains('nice', $locks);
+ }
- $this->instance->releaseLock('foo');
+ /**
+ * @small
+ */
+ public function testGetLocksWithPrefix()
+ {
+ self::assertTrue($this->instance->acquire('foo', 1));
+ self::assertTrue($this->instance->acquire('test1', 1));
+ self::assertTrue($this->instance->acquire('test2', 1));
- $this->assertFalse($this->instance->isLocked('foo'));
- $this->assertTrue($this->instance->isLocked('bar'));
- $this->assertTrue($this->instance->isLocked('nice'));
+ self::assertTrue($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->isLocked('test1'));
+ self::assertTrue($this->instance->isLocked('test2'));
- $this->instance->releaseAll();
+ $locks = $this->instance->getLocks('test');
- $this->assertFalse($this->instance->isLocked('bar'));
- $this->assertFalse($this->instance->isLocked('nice'));
+ self::assertContains('test1', $locks);
+ self::assertContains('test2', $locks);
+ self::assertNotContains('foo', $locks);
}
- function testLockTTL() {
+ /**
+ * @medium
+ */
+ public function testLockTTL()
+ {
+ static::markTestSkipped('taking too much time without mocking');
+
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertFalse($this->instance->isLocked('bar'));
// TODO [nupplaphil] - Because of the Datetime-Utils for the database, we have to wait a FULL second between the checks to invalidate the db-locks/cache
- $this->instance->acquireLock('foo', 1, 1);
- $this->instance->acquireLock('bar', 1, 3);
+ self::assertTrue($this->instance->acquire('foo', 2, 1));
+ self::assertTrue($this->instance->acquire('bar', 2, 3));
- $this->assertTrue($this->instance->isLocked('foo'));
- $this->assertTrue($this->instance->isLocked('bar'));
+ self::assertTrue($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->isLocked('bar'));
sleep(2);
- $this->assertFalse($this->instance->isLocked('foo'));
- $this->assertTrue($this->instance->isLocked('bar'));
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertTrue($this->instance->isLocked('bar'));
sleep(2);
- $this->assertFalse($this->instance->isLocked('foo'));
- $this->assertFalse($this->instance->isLocked('bar'));
+ self::assertFalse($this->instance->isLocked('foo'));
+ self::assertFalse($this->instance->isLocked('bar'));
+ }
+
+ /**
+ * Test if releasing a non-existing lock doesn't throw errors
+ */
+ public function testReleaseLockWithoutLock()
+ {
+ self::assertFalse($this->instance->isLocked('wrongLock'));
+ self::assertFalse($this->instance->release('wrongLock'));
}
}