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 $this->assertFalse($this->instance->isLocked('foo'));
60 $this->assertTrue($this->instance->acquire('foo', 1));
61 $this->assertTrue($this->instance->isLocked('foo'));
62 $this->assertFalse($this->instance->isLocked('bar'));
68 public function testDoubleLock()
70 $this->assertFalse($this->instance->isLocked('foo'));
71 $this->assertTrue($this->instance->acquire('foo', 1));
72 $this->assertTrue($this->instance->isLocked('foo'));
73 // We already locked it
74 $this->assertTrue($this->instance->acquire('foo', 1));
80 public function testReleaseLock()
82 $this->assertFalse($this->instance->isLocked('foo'));
83 $this->assertTrue($this->instance->acquire('foo', 1));
84 $this->assertTrue($this->instance->isLocked('foo'));
85 $this->instance->release('foo');
86 $this->assertFalse($this->instance->isLocked('foo'));
92 public function testReleaseAll()
94 $this->assertTrue($this->instance->acquire('foo', 1));
95 $this->assertTrue($this->instance->acquire('bar', 1));
96 $this->assertTrue($this->instance->acquire('nice', 1));
98 $this->assertTrue($this->instance->isLocked('foo'));
99 $this->assertTrue($this->instance->isLocked('bar'));
100 $this->assertTrue($this->instance->isLocked('nice'));
102 $this->assertTrue($this->instance->releaseAll());
104 $this->assertFalse($this->instance->isLocked('foo'));
105 $this->assertFalse($this->instance->isLocked('bar'));
106 $this->assertFalse($this->instance->isLocked('nice'));
112 public function testReleaseAfterUnlock()
114 $this->assertFalse($this->instance->isLocked('foo'));
115 $this->assertFalse($this->instance->isLocked('bar'));
116 $this->assertFalse($this->instance->isLocked('nice'));
117 $this->assertTrue($this->instance->acquire('foo', 1));
118 $this->assertTrue($this->instance->acquire('bar', 1));
119 $this->assertTrue($this->instance->acquire('nice', 1));
121 $this->assertTrue($this->instance->release('foo'));
123 $this->assertFalse($this->instance->isLocked('foo'));
124 $this->assertTrue($this->instance->isLocked('bar'));
125 $this->assertTrue($this->instance->isLocked('nice'));
127 $this->assertTrue($this->instance->releaseAll());
129 $this->assertFalse($this->instance->isLocked('bar'));
130 $this->assertFalse($this->instance->isLocked('nice'));
136 public function testReleaseWitTTL()
138 $this->assertFalse($this->instance->isLocked('test'));
139 $this->assertTrue($this->instance->acquire('test', 1, 10));
140 $this->assertTrue($this->instance->isLocked('test'));
141 $this->assertTrue($this->instance->release('test'));
142 $this->assertFalse($this->instance->isLocked('test'));
148 public function testGetLocks()
150 $this->assertTrue($this->instance->acquire('foo', 1));
151 $this->assertTrue($this->instance->acquire('bar', 1));
152 $this->assertTrue($this->instance->acquire('nice', 1));
154 $this->assertTrue($this->instance->isLocked('foo'));
155 $this->assertTrue($this->instance->isLocked('bar'));
156 $this->assertTrue($this->instance->isLocked('nice'));
158 $locks = $this->instance->getLocks();
160 $this->assertContains('foo', $locks);
161 $this->assertContains('bar', $locks);
162 $this->assertContains('nice', $locks);
168 public function testGetLocksWithPrefix()
170 $this->assertTrue($this->instance->acquire('foo', 1));
171 $this->assertTrue($this->instance->acquire('test1', 1));
172 $this->assertTrue($this->instance->acquire('test2', 1));
174 $this->assertTrue($this->instance->isLocked('foo'));
175 $this->assertTrue($this->instance->isLocked('test1'));
176 $this->assertTrue($this->instance->isLocked('test2'));
178 $locks = $this->instance->getLocks('test');
180 $this->assertContains('test1', $locks);
181 $this->assertContains('test2', $locks);
182 $this->assertNotContains('foo', $locks);
188 function testLockTTL()
190 $this->markTestSkipped('taking too much time without mocking');
192 $this->assertFalse($this->instance->isLocked('foo'));
193 $this->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 $this->assertTrue($this->instance->acquire('foo', 2, 1));
197 $this->assertTrue($this->instance->acquire('bar', 2, 3));
199 $this->assertTrue($this->instance->isLocked('foo'));
200 $this->assertTrue($this->instance->isLocked('bar'));
204 $this->assertFalse($this->instance->isLocked('foo'));
205 $this->assertTrue($this->instance->isLocked('bar'));
209 $this->assertFalse($this->instance->isLocked('foo'));
210 $this->assertFalse($this->instance->isLocked('bar'));
214 * Test if releasing a non-existing lock doesn't throw errors
216 public function testReleaseLockWithoutLock()
218 $this->assertFalse($this->instance->isLocked('wrongLock'));
219 $this->assertFalse($this->instance->release('wrongLock'));