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\Core\Lock\ILock;
25 use Friendica\Test\MockedTest;
27 abstract class LockTest extends MockedTest
30 * @var int Start time of the mock (used for time operations)
32 protected $startTime = 1417011228;
39 abstract protected function getInstance();
41 protected function setUp()
45 $this->instance = $this->getInstance();
46 $this->instance->releaseAll(true);
49 protected function tearDown()
51 $this->instance->releaseAll(true);
58 public function testLock()
60 self::assertFalse($this->instance->isLocked('foo'));
61 self::assertTrue($this->instance->acquire('foo', 1));
62 self::assertTrue($this->instance->isLocked('foo'));
63 self::assertFalse($this->instance->isLocked('bar'));
69 public function testDoubleLock()
71 self::assertFalse($this->instance->isLocked('foo'));
72 self::assertTrue($this->instance->acquire('foo', 1));
73 self::assertTrue($this->instance->isLocked('foo'));
74 // We already locked it
75 self::assertTrue($this->instance->acquire('foo', 1));
81 public function testReleaseLock()
83 self::assertFalse($this->instance->isLocked('foo'));
84 self::assertTrue($this->instance->acquire('foo', 1));
85 self::assertTrue($this->instance->isLocked('foo'));
86 $this->instance->release('foo');
87 self::assertFalse($this->instance->isLocked('foo'));
93 public function testReleaseAll()
95 self::assertTrue($this->instance->acquire('foo', 1));
96 self::assertTrue($this->instance->acquire('bar', 1));
97 self::assertTrue($this->instance->acquire('nice', 1));
99 self::assertTrue($this->instance->isLocked('foo'));
100 self::assertTrue($this->instance->isLocked('bar'));
101 self::assertTrue($this->instance->isLocked('nice'));
103 self::assertTrue($this->instance->releaseAll());
105 self::assertFalse($this->instance->isLocked('foo'));
106 self::assertFalse($this->instance->isLocked('bar'));
107 self::assertFalse($this->instance->isLocked('nice'));
113 public function testReleaseAfterUnlock()
115 self::assertFalse($this->instance->isLocked('foo'));
116 self::assertFalse($this->instance->isLocked('bar'));
117 self::assertFalse($this->instance->isLocked('nice'));
118 self::assertTrue($this->instance->acquire('foo', 1));
119 self::assertTrue($this->instance->acquire('bar', 1));
120 self::assertTrue($this->instance->acquire('nice', 1));
122 self::assertTrue($this->instance->release('foo'));
124 self::assertFalse($this->instance->isLocked('foo'));
125 self::assertTrue($this->instance->isLocked('bar'));
126 self::assertTrue($this->instance->isLocked('nice'));
128 self::assertTrue($this->instance->releaseAll());
130 self::assertFalse($this->instance->isLocked('bar'));
131 self::assertFalse($this->instance->isLocked('nice'));
137 public function testReleaseWitTTL()
139 self::assertFalse($this->instance->isLocked('test'));
140 self::assertTrue($this->instance->acquire('test', 1, 10));
141 self::assertTrue($this->instance->isLocked('test'));
142 self::assertTrue($this->instance->release('test'));
143 self::assertFalse($this->instance->isLocked('test'));
149 public function testGetLocks()
151 self::assertTrue($this->instance->acquire('foo', 1));
152 self::assertTrue($this->instance->acquire('bar', 1));
153 self::assertTrue($this->instance->acquire('nice', 1));
155 self::assertTrue($this->instance->isLocked('foo'));
156 self::assertTrue($this->instance->isLocked('bar'));
157 self::assertTrue($this->instance->isLocked('nice'));
159 $locks = $this->instance->getLocks();
161 self::assertContains('foo', $locks);
162 self::assertContains('bar', $locks);
163 self::assertContains('nice', $locks);
169 public function testGetLocksWithPrefix()
171 self::assertTrue($this->instance->acquire('foo', 1));
172 self::assertTrue($this->instance->acquire('test1', 1));
173 self::assertTrue($this->instance->acquire('test2', 1));
175 self::assertTrue($this->instance->isLocked('foo'));
176 self::assertTrue($this->instance->isLocked('test1'));
177 self::assertTrue($this->instance->isLocked('test2'));
179 $locks = $this->instance->getLocks('test');
181 self::assertContains('test1', $locks);
182 self::assertContains('test2', $locks);
183 self::assertNotContains('foo', $locks);
189 public function testLockTTL()
191 static::markTestSkipped('taking too much time without mocking');
193 self::assertFalse($this->instance->isLocked('foo'));
194 self::assertFalse($this->instance->isLocked('bar'));
196 // 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
197 self::assertTrue($this->instance->acquire('foo', 2, 1));
198 self::assertTrue($this->instance->acquire('bar', 2, 3));
200 self::assertTrue($this->instance->isLocked('foo'));
201 self::assertTrue($this->instance->isLocked('bar'));
205 self::assertFalse($this->instance->isLocked('foo'));
206 self::assertTrue($this->instance->isLocked('bar'));
210 self::assertFalse($this->instance->isLocked('foo'));
211 self::assertFalse($this->instance->isLocked('bar'));
215 * Test if releasing a non-existing lock doesn't throw errors
217 public function testReleaseLockWithoutLock()
219 self::assertFalse($this->instance->isLocked('wrongLock'));
220 self::assertFalse($this->instance->release('wrongLock'));