]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/Lock/LockTest.php
Merge pull request #10703 from tobiasd/20210913-fr
[friendica.git] / tests / src / Core / Lock / LockTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
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.
11  *
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.
16  *
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/>.
19  *
20  */
21
22 namespace Friendica\Test\src\Core\Lock;
23
24 use Friendica\Core\Lock\ILock;
25 use Friendica\Test\MockedTest;
26
27 abstract class LockTest extends MockedTest
28 {
29         /**
30          * @var int Start time of the mock (used for time operations)
31          */
32         protected $startTime = 1417011228;
33
34         /**
35          * @var ILock
36          */
37         protected $instance;
38
39         abstract protected function getInstance();
40
41         protected function setUp(): void
42         {
43                 parent::setUp();
44
45                 $this->instance = $this->getInstance();
46                 $this->instance->releaseAll(true);
47         }
48
49         protected function tearDown(): void
50         {
51                 $this->instance->releaseAll(true);
52                 parent::tearDown();
53         }
54
55         /**
56          * @small
57          */
58         public function testLock()
59         {
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'));
64         }
65
66         /**
67          * @small
68          */
69         public function testDoubleLock()
70         {
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));
76         }
77
78         /**
79          * @small
80          */
81         public function testReleaseLock()
82         {
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'));
88         }
89
90         /**
91          * @small
92          */
93         public function testReleaseAll()
94         {
95                 self::assertTrue($this->instance->acquire('foo', 1));
96                 self::assertTrue($this->instance->acquire('bar', 1));
97                 self::assertTrue($this->instance->acquire('nice', 1));
98
99                 self::assertTrue($this->instance->isLocked('foo'));
100                 self::assertTrue($this->instance->isLocked('bar'));
101                 self::assertTrue($this->instance->isLocked('nice'));
102
103                 self::assertTrue($this->instance->releaseAll());
104
105                 self::assertFalse($this->instance->isLocked('foo'));
106                 self::assertFalse($this->instance->isLocked('bar'));
107                 self::assertFalse($this->instance->isLocked('nice'));
108         }
109
110         /**
111          * @small
112          */
113         public function testReleaseAfterUnlock()
114         {
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));
121
122                 self::assertTrue($this->instance->release('foo'));
123
124                 self::assertFalse($this->instance->isLocked('foo'));
125                 self::assertTrue($this->instance->isLocked('bar'));
126                 self::assertTrue($this->instance->isLocked('nice'));
127
128                 self::assertTrue($this->instance->releaseAll());
129
130                 self::assertFalse($this->instance->isLocked('bar'));
131                 self::assertFalse($this->instance->isLocked('nice'));
132         }
133
134         /**
135          * @small
136          */
137         public function testReleaseWitTTL()
138         {
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'));
144         }
145
146         /**
147          * @small
148          */
149         public function testGetLocks()
150         {
151                 self::assertTrue($this->instance->acquire('foo', 1));
152                 self::assertTrue($this->instance->acquire('bar', 1));
153                 self::assertTrue($this->instance->acquire('nice', 1));
154
155                 self::assertTrue($this->instance->isLocked('foo'));
156                 self::assertTrue($this->instance->isLocked('bar'));
157                 self::assertTrue($this->instance->isLocked('nice'));
158
159                 $locks = $this->instance->getLocks();
160
161                 self::assertContains('foo', $locks);
162                 self::assertContains('bar', $locks);
163                 self::assertContains('nice', $locks);
164         }
165
166         /**
167          * @small
168          */
169         public function testGetLocksWithPrefix()
170         {
171                 self::assertTrue($this->instance->acquire('foo', 1));
172                 self::assertTrue($this->instance->acquire('test1', 1));
173                 self::assertTrue($this->instance->acquire('test2', 1));
174
175                 self::assertTrue($this->instance->isLocked('foo'));
176                 self::assertTrue($this->instance->isLocked('test1'));
177                 self::assertTrue($this->instance->isLocked('test2'));
178
179                 $locks = $this->instance->getLocks('test');
180
181                 self::assertContains('test1', $locks);
182                 self::assertContains('test2', $locks);
183                 self::assertNotContains('foo', $locks);
184         }
185
186         /**
187          * @medium
188          */
189         public function testLockTTL()
190         {
191                 static::markTestSkipped('taking too much time without mocking');
192
193                 self::assertFalse($this->instance->isLocked('foo'));
194                 self::assertFalse($this->instance->isLocked('bar'));
195
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));
199
200                 self::assertTrue($this->instance->isLocked('foo'));
201                 self::assertTrue($this->instance->isLocked('bar'));
202
203                 sleep(2);
204
205                 self::assertFalse($this->instance->isLocked('foo'));
206                 self::assertTrue($this->instance->isLocked('bar'));
207
208                 sleep(2);
209
210                 self::assertFalse($this->instance->isLocked('foo'));
211                 self::assertFalse($this->instance->isLocked('bar'));
212         }
213
214         /**
215          * Test if releasing a non-existing lock doesn't throw errors
216          */
217         public function testReleaseLockWithoutLock()
218         {
219                 self::assertFalse($this->instance->isLocked('wrongLock'));
220                 self::assertFalse($this->instance->release('wrongLock'));
221         }
222 }