]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/StorageManagerTest.php
Removed structure check
[friendica.git] / tests / src / Core / StorageManagerTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
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;
23
24 use Dice\Dice;
25 use Friendica\Core\Config\IConfig;
26 use Friendica\Core\Config\PreloadConfig;
27 use Friendica\Core\Hook;
28 use Friendica\Core\L10n;
29 use Friendica\Core\Session\ISession;
30 use Friendica\Core\StorageManager;
31 use Friendica\Database\Database;
32 use Friendica\DI;
33 use Friendica\Factory\ConfigFactory;
34 use Friendica\Model\Config\Config;
35 use Friendica\Model\Storage;
36 use Friendica\Core\Session;
37 use Friendica\Database\DBStructure;
38 use Friendica\Test\DatabaseTest;
39 use Friendica\Test\Util\Database\StaticDatabase;
40 use Friendica\Test\Util\VFSTrait;
41 use Friendica\Util\ConfigFileLoader;
42 use Friendica\Util\Profiler;
43 use Psr\Log\LoggerInterface;
44 use Psr\Log\NullLogger;
45 use Friendica\Test\Util\SampleStorageBackend;
46
47 class StorageManagerTest extends DatabaseTest
48 {
49         /** @var Database */
50         private $dba;
51         /** @var IConfig */
52         private $config;
53         /** @var LoggerInterface */
54         private $logger;
55         /** @var L10n */
56         private $l10n;
57
58         use VFSTrait;
59
60         public function setUp()
61         {
62                 parent::setUp();
63
64                 $this->setUpVfsDir();
65
66                 $this->logger = new NullLogger();
67
68                 $profiler = \Mockery::mock(Profiler::class);
69                 $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
70
71                 // load real config to avoid mocking every config-entry which is related to the Database class
72                 $configFactory = new ConfigFactory();
73                 $loader        = new ConfigFileLoader($this->root->url());
74                 $configCache   = $configFactory->createCache($loader);
75
76                 $this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
77
78                 $this->dba->setTestmode(true);
79
80                 $configModel  = new Config($this->dba);
81                 $this->config = new PreloadConfig($configCache, $configModel);
82
83                 $this->l10n = \Mockery::mock(L10n::class);
84         }
85
86         /**
87          * Test plain instancing first
88          */
89         public function testInstance()
90         {
91                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
92
93                 $this->assertInstanceOf(StorageManager::class, $storageManager);
94         }
95
96         public function dataStorages()
97         {
98                 return [
99                         'empty'          => [
100                                 'name'        => '',
101                                 'assert'      => null,
102                                 'assertName'  => '',
103                                 'userBackend' => false,
104                         ],
105                         'database'       => [
106                                 'name'        => Storage\Database::NAME,
107                                 'assert'      => Storage\Database::class,
108                                 'assertName'  => Storage\Database::NAME,
109                                 'userBackend' => true,
110                         ],
111                         'filesystem'     => [
112                                 'name'        => Storage\Filesystem::NAME,
113                                 'assert'      => Storage\Filesystem::class,
114                                 'assertName'  => Storage\Filesystem::NAME,
115                                 'userBackend' => true,
116                         ],
117                         'systemresource' => [
118                                 'name'        => Storage\SystemResource::NAME,
119                                 'assert'      => Storage\SystemResource::class,
120                                 'assertName'  => Storage\SystemResource::NAME,
121                                 // false here, because SystemResource isn't meant to be a user backend,
122                                 // it's for system resources only
123                                 'userBackend' => false,
124                         ],
125                         'invalid'        => [
126                                 'name'        => 'invalid',
127                                 'assert'      => null,
128                                 'assertName'  => '',
129                                 'userBackend' => false,
130                         ],
131                 ];
132         }
133
134         /**
135          * Data array for legacy backends
136          *
137          * @todo 2020.09 After 2 releases, remove the legacy functionality and these data array with it
138          *
139          * @return array
140          */
141         public function dataLegacyBackends()
142         {
143                 return [
144                         'legacyDatabase'          => [
145                                 'name'        => 'Friendica\Model\Storage\Database',
146                                 'assert'      => Storage\Database::class,
147                                 'assertName'  => Storage\Database::NAME,
148                                 'userBackend' => true,
149                         ],
150                         'legacyFilesystem'       => [
151                                 'name'        => 'Friendica\Model\Storage\Filesystem',
152                                 'assert'      => Storage\Filesystem::class,
153                                 'assertName'  => Storage\Filesystem::NAME,
154                                 'userBackend' => true,
155                         ],
156                         'legacySystemResource'     => [
157                                 'name'        => 'Friendica\Model\Storage\SystemResource',
158                                 'assert'      => Storage\SystemResource::class,
159                                 'assertName'  => Storage\SystemResource::NAME,
160                                 'userBackend' => false,
161                         ],
162                 ];
163         }
164
165         /**
166          * Test the getByName() method
167          *
168          * @dataProvider dataStorages
169          * @dataProvider dataLegacyBackends
170          */
171         public function testGetByName($name, $assert, $assertName, $userBackend)
172         {
173                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
174
175                 $storage = $storageManager->getByName($name, $userBackend);
176
177                 if (!empty($assert)) {
178                         $this->assertInstanceOf(Storage\IStorage::class, $storage);
179                         $this->assertInstanceOf($assert, $storage);
180                 } else {
181                         $this->assertNull($storage);
182                 }
183                 $this->assertEquals($assertName, $storage);
184         }
185
186         /**
187          * Test the isValidBackend() method
188          *
189          * @dataProvider dataStorages
190          */
191         public function testIsValidBackend($name, $assert, $assertName, $userBackend)
192         {
193                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
194
195                 // true in every of the backends
196                 $this->assertEquals(!empty($assertName), $storageManager->isValidBackend($name));
197
198                 // if userBackend is set to true, filter out e.g. SystemRessource
199                 $this->assertEquals($userBackend, $storageManager->isValidBackend($name, true));
200         }
201
202         /**
203          * Test the method listBackends() with default setting
204          */
205         public function testListBackends()
206         {
207                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
208
209                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
210         }
211
212         /**
213          * Test the method getBackend()
214          *
215          * @dataProvider dataStorages
216          */
217         public function testGetBackend($name, $assert, $assertName, $userBackend)
218         {
219                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
220
221                 $this->assertNull($storageManager->getBackend());
222
223                 if ($userBackend) {
224                         $storageManager->setBackend($name);
225
226                         $this->assertInstanceOf($assert, $storageManager->getBackend());
227                 }
228         }
229
230         /**
231          * Test the method getBackend() with a pre-configured backend
232          *
233          * @dataProvider dataStorages
234          * @dataProvider dataLegacyBackends
235          */
236         public function testPresetBackend($name, $assert, $assertName, $userBackend)
237         {
238                 $this->config->set('storage', 'name', $name);
239
240                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
241
242                 if ($userBackend) {
243                         $this->assertInstanceOf($assert, $storageManager->getBackend());
244                 } else {
245                         $this->assertNull($storageManager->getBackend());
246                 }
247         }
248
249         /**
250          * Tests the register and unregister methods for a new backend storage class
251          *
252          * Uses a sample storage for testing
253          *
254          * @see SampleStorageBackend
255          */
256         public function testRegisterUnregisterBackends()
257         {
258                 /// @todo Remove dice once "Hook" is dynamic and mockable
259                 $dice   = (new Dice())
260                         ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
261                         ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
262                         ->addRule(ISession::class, ['instanceOf' => Session\Memory::class, 'shared' => true, 'call' => null]);
263                 DI::init($dice);
264
265                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
266
267                 $this->assertTrue($storageManager->register(SampleStorageBackend::class));
268
269                 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
270                         SampleStorageBackend::getName() => SampleStorageBackend::class,
271                 ]), $storageManager->listBackends());
272                 $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
273                         SampleStorageBackend::getName() => SampleStorageBackend::class,
274                 ]), $this->config->get('storage', 'backends'));
275
276                 // inline call to register own class as hook (testing purpose only)
277                 SampleStorageBackend::registerHook();
278                 Hook::loadHooks();
279
280                 $this->assertTrue($storageManager->setBackend(SampleStorageBackend::NAME));
281                 $this->assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
282
283                 $this->assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
284
285                 $this->assertTrue($storageManager->unregister(SampleStorageBackend::class));
286                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $this->config->get('storage', 'backends'));
287                 $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
288
289                 $this->assertNull($storageManager->getBackend());
290                 $this->assertNull($this->config->get('storage', 'name'));
291         }
292
293         /**
294          * Test moving data to a new storage (currently testing db & filesystem)
295          *
296          * @dataProvider dataStorages
297          */
298         public function testMoveStorage($name, $assert, $assertName, $userBackend)
299         {
300                 if (!$userBackend) {
301                         return;
302                 }
303
304                 $this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba);
305
306                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
307                 $storage = $storageManager->getByName($name);
308                 $storageManager->move($storage);
309
310                 $photos = $this->dba->select('photo', ['backend-ref', 'backend-class', 'id', 'data']);
311
312                 while ($photo = $this->dba->fetch($photos)) {
313
314                         $this->assertEmpty($photo['data']);
315
316                         $storage = $storageManager->getByName($photo['backend-class']);
317                         $data = $storage->get($photo['backend-ref']);
318
319                         $this->assertNotEmpty($data);
320                 }
321         }
322
323         /**
324          * Test moving data to a WRONG storage
325          *
326          * @expectedException \Friendica\Model\Storage\StorageException
327          * @expectedExceptionMessage Can't move to storage backend 'SystemResource'
328          */
329         public function testMoveStorageWrong()
330         {
331                 $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
332                 $storage = $storageManager->getByName(Storage\SystemResource::getName());
333                 $storageManager->move($storage);
334         }
335 }