3 * @copyright Copyright (C) 2020, Friendica
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Test\src\Core\Lock;
24 use Friendica\Test\MockedTest;
26 abstract class LockTest extends MockedTest
29 * @var int Start time of the mock (used for time operations)
31 protected $startTime = 1417011228;
34 * @var \Friendica\Core\Lock\ILock
38 abstract protected function getInstance();
40 protected function setUp()
44 $this->instance = $this->getInstance();
45 $this->instance->releaseAll(true);
48 protected function tearDown()
50 $this->instance->releaseAll(true);
57 public function testLock()
59 self::assertFalse($this->instance->isLocked('foo'));
60 self::assertTrue($this->instance->acquire('foo', 1));
61 self::assertTrue($this->instance->isLocked('foo'));
62 self::assertFalse($this->instance->isLocked('bar'));
68 public function testDoubleLock()
70 self::assertFalse($this->instance->isLocked('foo'));
71 self::assertTrue($this->instance->acquire('foo', 1));
72 self::assertTrue($this->instance->isLocked('foo'));
73 // We already locked it
74 self::assertTrue($this->instance->acquire('foo', 1));
80 public function testReleaseLock()
82 self::assertFalse($this->instance->isLocked('foo'));
83 self::assertTrue($this->instance->acquire('foo', 1));
84 self::assertTrue($this->instance->isLocked('foo'));
85 $this->instance->release('foo');
86 self::assertFalse($this->instance->isLocked('foo'));
92 public function testReleaseAll()
94 self::assertTrue($this->instance->acquire('foo', 1));
95 self::assertTrue($this->instance->acquire('bar', 1));
96 self::assertTrue($this->instance->acquire('nice', 1));
98 self::assertTrue($this->instance->isLocked('foo'));
99 self::assertTrue($this->instance->isLocked('bar'));
100 self::assertTrue($this->instance->isLocked('nice'));
102 self::assertTrue($this->instance->releaseAll());
104 self::assertFalse($this->instance->isLocked('foo'));
105 self::assertFalse($this->instance->isLocked('bar'));
106 self::assertFalse($this->instance->isLocked('nice'));
112 public function testReleaseAfterUnlock()
114 self::assertFalse($this->instance->isLocked('foo'));
115 self::assertFalse($this->instance->isLocked('bar'));
116 self::assertFalse($this->instance->isLocked('nice'));
117 self::assertTrue($this->instance->acquire('foo', 1));
118 self::assertTrue($this->instance->acquire('bar', 1));
119 self::assertTrue($this->instance->acquire('nice', 1));
121 self::assertTrue($this->instance->release('foo'));
123 self::assertFalse($this->instance->isLocked('foo'));
124 self::assertTrue($this->instance->isLocked('bar'));
125 self::assertTrue($this->instance->isLocked('nice'));
127 self::assertTrue($this->instance->releaseAll());
129 self::assertFalse($this->instance->isLocked('bar'));
130 self::assertFalse($this->instance->isLocked('nice'));
136 public function testReleaseWitTTL()
138 self::assertFalse($this->instance->isLocked('test'));
139 self::assertTrue($this->instance->acquire('test', 1, 10));
140 self::assertTrue($this->instance->isLocked('test'));
141 self::assertTrue($this->instance->release('test'));
142 self::assertFalse($this->instance->isLocked('test'));
148 public function testGetLocks()
150 self::assertTrue($this->instance->acquire('foo', 1));
151 self::assertTrue($this->instance->acquire('bar', 1));
152 self::assertTrue($this->instance->acquire('nice', 1));
154 self::assertTrue($this->instance->isLocked('foo'));
155 self::assertTrue($this->instance->isLocked('bar'));
156 self::assertTrue($this->instance->isLocked('nice'));
158 $locks = $this->instance->getLocks();
160 self::assertContains('foo', $locks);
161 self::assertContains('bar', $locks);
162 self::assertContains('nice', $locks);
168 public function testGetLocksWithPrefix()
170 self::assertTrue($this->instance->acquire('foo', 1));
171 self::assertTrue($this->instance->acquire('test1', 1));
172 self::assertTrue($this->instance->acquire('test2', 1));
174 self::assertTrue($this->instance->isLocked('foo'));
175 self::assertTrue($this->instance->isLocked('test1'));
176 self::assertTrue($this->instance->isLocked('test2'));
178 $locks = $this->instance->getLocks('test');
180 self::assertContains('test1', $locks);
181 self::assertContains('test2', $locks);
182 self::assertNotContains('foo', $locks);
188 function testLockTTL()
190 $this->markTestSkipped('taking too much time without mocking');
192 self::assertFalse($this->instance->isLocked('foo'));
193 self::assertFalse($this->instance->isLocked('bar'));
195 // 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
196 self::assertTrue($this->instance->acquire('foo', 2, 1));
197 self::assertTrue($this->instance->acquire('bar', 2, 3));
199 self::assertTrue($this->instance->isLocked('foo'));
200 self::assertTrue($this->instance->isLocked('bar'));
204 self::assertFalse($this->instance->isLocked('foo'));
205 self::assertTrue($this->instance->isLocked('bar'));
209 self::assertFalse($this->instance->isLocked('foo'));
210 self::assertFalse($this->instance->isLocked('bar'));
214 * Test if releasing a non-existing lock doesn't throw errors
216 public function testReleaseLockWithoutLock()
218 self::assertFalse($this->instance->isLocked('wrongLock'));
219 self::assertFalse($this->instance->release('wrongLock'));