<?php
/**
- * @copyright Copyright (C) 2020, Friendica
+ * @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
use Friendica\Model\Config\Config;
use Friendica\Model\Storage;
use Friendica\Core\Session;
-use Friendica\Database\DBStructure;
+use Friendica\Network\HTTPClient;
use Friendica\Test\DatabaseTest;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait;
use Friendica\Util\ConfigFileLoader;
use Friendica\Util\Profiler;
+use org\bovigo\vfs\vfsStream;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Friendica\Test\Util\SampleStorageBackend;
class StorageManagerTest extends DatabaseTest
{
+ use VFSTrait;
/** @var Database */
private $dba;
/** @var IConfig */
private $logger;
/** @var L10n */
private $l10n;
+ /** @var HTTPClient */
+ private $httpRequest;
- use VFSTrait;
-
- public function setUp()
+ protected function setUp(): void
{
parent::setUp();
$this->setUpVfsDir();
+ vfsStream::newDirectory(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER, 0777)->at($this->root);
+
$this->logger = new NullLogger();
$profiler = \Mockery::mock(Profiler::class);
+ $profiler->shouldReceive('startRecording');
+ $profiler->shouldReceive('stopRecording');
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
// load real config to avoid mocking every config-entry which is related to the Database class
$configFactory = new ConfigFactory();
- $loader = new ConfigFileLoader($this->root->url());
+ $loader = $configFactory->createConfigFileLoader($this->root->url(), []);
$configCache = $configFactory->createCache($loader);
$this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
- $this->dba->setTestmode(true);
-
- DBStructure::checkInitialValues();
-
$configModel = new Config($this->dba);
$this->config = new PreloadConfig($configCache, $configModel);
+ $this->config->set('storage', 'name', 'Database');
+ $this->config->set('storage', 'filesystem_path', $this->root->getChild(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER)->url());
$this->l10n = \Mockery::mock(L10n::class);
+
+ $this->httpRequest = \Mockery::mock(HTTPClient::class);
+ }
+
+ protected function tearDown(): void
+ {
+ $this->root->removeChild(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER);
+
+ parent::tearDown();
}
/**
*/
public function testInstance()
{
- $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
+ $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n, $this->httpRequest);
- $this->assertInstanceOf(StorageManager::class, $storageManager);
+ self::assertInstanceOf(StorageManager::class, $storageManager);
}
public function dataStorages()
{
return [
- 'empty' => [
- 'name' => '',
- 'assert' => null,
- 'assertName' => '',
- 'userBackend' => false,
+ 'empty' => [
+ 'name' => '',
+ 'valid' => false,
+ 'interface' => Storage\IStorage::class,
+ 'assert' => null,
+ 'assertName' => '',
],
- 'database' => [
- 'name' => Storage\Database::NAME,
- 'assert' => Storage\Database::class,
- 'assertName' => Storage\Database::NAME,
- 'userBackend' => true,
+ 'database' => [
+ 'name' => Storage\Database::NAME,
+ 'valid' => true,
+ 'interface' => Storage\IWritableStorage::class,
+ 'assert' => Storage\Database::class,
+ 'assertName' => Storage\Database::NAME,
],
- 'filesystem' => [
- 'name' => Storage\Filesystem::NAME,
- 'assert' => Storage\Filesystem::class,
- 'assertName' => Storage\Filesystem::NAME,
- 'userBackend' => true,
+ 'filesystem' => [
+ 'name' => Storage\Filesystem::NAME,
+ 'valid' => true,
+ 'interface' => Storage\IWritableStorage::class,
+ 'assert' => Storage\Filesystem::class,
+ 'assertName' => Storage\Filesystem::NAME,
],
'systemresource' => [
- 'name' => Storage\SystemResource::NAME,
- 'assert' => Storage\SystemResource::class,
- 'assertName' => Storage\SystemResource::NAME,
- // false here, because SystemResource isn't meant to be a user backend,
- // it's for system resources only
- 'userBackend' => false,
+ 'name' => Storage\SystemResource::NAME,
+ 'valid' => true,
+ 'interface' => Storage\IStorage::class,
+ 'assert' => Storage\SystemResource::class,
+ 'assertName' => Storage\SystemResource::NAME,
],
- 'invalid' => [
+ 'invalid' => [
'name' => 'invalid',
+ 'valid' => false,
+ 'interface' => null,
'assert' => null,
'assertName' => '',
'userBackend' => false,
];
}
- /**
- * Data array for legacy backends
- *
- * @todo 2020.09 After 2 releases, remove the legacy functionality and these data array with it
- *
- * @return array
- */
- public function dataLegacyBackends()
- {
- return [
- 'legacyDatabase' => [
- 'name' => 'Friendica\Model\Storage\Database',
- 'assert' => Storage\Database::class,
- 'assertName' => Storage\Database::NAME,
- 'userBackend' => true,
- ],
- 'legacyFilesystem' => [
- 'name' => 'Friendica\Model\Storage\Filesystem',
- 'assert' => Storage\Filesystem::class,
- 'assertName' => Storage\Filesystem::NAME,
- 'userBackend' => true,
- ],
- 'legacySystemResource' => [
- 'name' => 'Friendica\Model\Storage\SystemResource',
- 'assert' => Storage\SystemResource::class,
- 'assertName' => Storage\SystemResource::NAME,
- 'userBackend' => false,
- ],
- ];
- }
-
/**
* Test the getByName() method
*
* @dataProvider dataStorages
- * @dataProvider dataLegacyBackends
*/
- public function testGetByName($name, $assert, $assertName, $userBackend)
+ public function testGetByName($name, $valid, $interface, $assert, $assertName)
{
- $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
+ if (!$valid) {
+ $this->expectException(Storage\InvalidClassStorageException::class);
+ }
- $storage = $storageManager->getByName($name, $userBackend);
+ if ($interface === Storage\IWritableStorage::class) {
+ $this->config->set('storage', 'name', $name);
+ }
+
+ $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- if (!empty($assert)) {
- $this->assertInstanceOf(Storage\IStorage::class, $storage);
- $this->assertInstanceOf($assert, $storage);
+ if ($interface === Storage\IWritableStorage::class) {
+ $storage = $storageManager->getWritableStorageByName($name);
} else {
- $this->assertNull($storage);
+ $storage = $storageManager->getByName($name);
}
- $this->assertEquals($assertName, $storage);
+
+ self::assertInstanceOf($interface, $storage);
+ self::assertInstanceOf($assert, $storage);
+ self::assertEquals($assertName, $storage);
}
/**
*
* @dataProvider dataStorages
*/
- public function testIsValidBackend($name, $assert, $assertName, $userBackend)
+ public function testIsValidBackend($name, $valid, $interface, $assert, $assertName)
{
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
// true in every of the backends
- $this->assertEquals(!empty($assertName), $storageManager->isValidBackend($name));
+ self::assertEquals(!empty($assertName), $storageManager->isValidBackend($name));
- // if userBackend is set to true, filter out e.g. SystemRessource
- $this->assertEquals($userBackend, $storageManager->isValidBackend($name, true));
+ // if it's a IWritableStorage, the valid backend should return true, otherwise false
+ self::assertEquals($interface === Storage\IWritableStorage::class, $storageManager->isValidBackend($name, StorageManager::DEFAULT_BACKENDS));
}
/**
{
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
+ self::assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
}
/**
*
* @dataProvider dataStorages
*/
- public function testGetBackend($name, $assert, $assertName, $userBackend)
+ public function testGetBackend($name, $valid, $interface, $assert, $assertName)
{
- $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
+ if ($interface !== Storage\IWritableStorage::class) {
+ static::markTestSkipped('only works for IWritableStorage');
+ }
- $this->assertNull($storageManager->getBackend());
+ $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- if ($userBackend) {
- $storageManager->setBackend($name);
+ $selBackend = $storageManager->getWritableStorageByName($name);
+ $storageManager->setBackend($selBackend);
- $this->assertInstanceOf($assert, $storageManager->getBackend());
- }
+ self::assertInstanceOf($assert, $storageManager->getBackend());
}
/**
* Test the method getBackend() with a pre-configured backend
*
* @dataProvider dataStorages
- * @dataProvider dataLegacyBackends
*/
- public function testPresetBackend($name, $assert, $assertName, $userBackend)
+ public function testPresetBackend($name, $valid, $interface, $assert, $assertName)
{
$this->config->set('storage', 'name', $name);
+ if ($interface !== Storage\IWritableStorage::class) {
+ $this->expectException(Storage\InvalidClassStorageException::class);
+ }
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- if ($userBackend) {
- $this->assertInstanceOf($assert, $storageManager->getBackend());
- } else {
- $this->assertNull($storageManager->getBackend());
- }
+ self::assertInstanceOf($assert, $storageManager->getBackend());
}
/**
public function testRegisterUnregisterBackends()
{
/// @todo Remove dice once "Hook" is dynamic and mockable
- $dice = (new Dice())
+ $dice = (new Dice())
->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
->addRule(ISession::class, ['instanceOf' => Session\Memory::class, 'shared' => true, 'call' => null]);
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- $this->assertTrue($storageManager->register(SampleStorageBackend::class));
+ self::assertTrue($storageManager->register(SampleStorageBackend::class));
- $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
- SampleStorageBackend::getName() => SampleStorageBackend::class,
+ self::assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
+ SampleStorageBackend::getName(),
]), $storageManager->listBackends());
- $this->assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
- SampleStorageBackend::getName() => SampleStorageBackend::class,
+ self::assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
+ SampleStorageBackend::getName()
+ ]), $this->config->get('storage', 'backends'));
+
+ self::assertTrue($storageManager->unregister(SampleStorageBackend::class));
+ self::assertEquals(StorageManager::DEFAULT_BACKENDS, $this->config->get('storage', 'backends'));
+ self::assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
+ }
+
+ /**
+ * tests that an active backend cannot get unregistered
+ */
+ public function testUnregisterActiveBackend()
+ {
+ /// @todo Remove dice once "Hook" is dynamic and mockable
+ $dice = (new Dice())
+ ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
+ ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
+ ->addRule(ISession::class, ['instanceOf' => Session\Memory::class, 'shared' => true, 'call' => null]);
+ DI::init($dice);
+
+ $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
+
+ self::assertTrue($storageManager->register(SampleStorageBackend::class));
+
+ self::assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
+ SampleStorageBackend::getName(),
+ ]), $storageManager->listBackends());
+ self::assertEquals(array_merge(StorageManager::DEFAULT_BACKENDS, [
+ SampleStorageBackend::getName()
]), $this->config->get('storage', 'backends'));
// inline call to register own class as hook (testing purpose only)
SampleStorageBackend::registerHook();
Hook::loadHooks();
- $this->assertTrue($storageManager->setBackend(SampleStorageBackend::NAME));
- $this->assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
+ self::assertTrue($storageManager->setBackend($storageManager->getWritableStorageByName(SampleStorageBackend::NAME)));
+ self::assertEquals(SampleStorageBackend::NAME, $this->config->get('storage', 'name'));
- $this->assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
+ self::assertInstanceOf(SampleStorageBackend::class, $storageManager->getBackend());
- $this->assertTrue($storageManager->unregister(SampleStorageBackend::class));
- $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $this->config->get('storage', 'backends'));
- $this->assertEquals(StorageManager::DEFAULT_BACKENDS, $storageManager->listBackends());
+ self::expectException(Storage\StorageException::class);
+ self::expectExceptionMessage('Cannot unregister Sample Storage, because it\'s currently active.');
- $this->assertNull($storageManager->getBackend());
- $this->assertNull($this->config->get('storage', 'name'));
+ $storageManager->unregister(SampleStorageBackend::class);
}
/**
*
* @dataProvider dataStorages
*/
- public function testMoveStorage($name, $assert, $assertName, $userBackend)
+ public function testMoveStorage($name, $valid, $interface, $assert, $assertName)
{
- if (!$userBackend) {
- return;
+ if ($interface !== Storage\IWritableStorage::class) {
+ self::markTestSkipped("No user backend");
}
$this->loadFixture(__DIR__ . '/../../datasets/storage/database.fixture.php', $this->dba);
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- $storage = $storageManager->getByName($name);
+ $storage = $storageManager->getWritableStorageByName($name);
$storageManager->move($storage);
$photos = $this->dba->select('photo', ['backend-ref', 'backend-class', 'id', 'data']);
while ($photo = $this->dba->fetch($photos)) {
-
- $this->assertEmpty($photo['data']);
+ self::assertEmpty($photo['data']);
$storage = $storageManager->getByName($photo['backend-class']);
- $data = $storage->get($photo['backend-ref']);
+ $data = $storage->get($photo['backend-ref']);
- $this->assertNotEmpty($data);
+ self::assertNotEmpty($data);
}
}
/**
* Test moving data to a WRONG storage
- *
- * @expectedException \Friendica\Model\Storage\StorageException
- * @expectedExceptionMessage Can't move to storage backend 'SystemResource'
*/
- public function testMoveStorageWrong()
+ public function testWrongWritableStorage()
{
+ $this->expectException(Storage\InvalidClassStorageException::class);
+ $this->expectExceptionMessage('Backend SystemResource is not valid');
+
$storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
- $storage = $storageManager->getByName(Storage\SystemResource::getName());
+ $storage = $storageManager->getWritableStorageByName(Storage\SystemResource::getName());
$storageManager->move($storage);
}
}