From 80d0450f5ceb16ca30f1d9a81fefba04f6118051 Mon Sep 17 00:00:00 2001 From: Abel Hoogeveen Date: Sun, 20 Dec 2020 19:43:02 +0100 Subject: [PATCH] Got the base working. - Working providers: Dummy, Redis and File - Component now delivers the selected storage based on its config file - Now provides ObjectStorageTest, a PSR CacheProvider compatible object to save and cache data in ObjectStorage --- .drone.yml | 0 .gitignore | 3 +- .../ObjectStorage/ObjectStorageCache.php | 128 +++++++++++ .../ObjectStorage/ObjectStorageComponent.php | 91 ++++++++ .../ObjectStorage/Provider/DummyProvider.php | 117 ++++++++++ .../ObjectStorage/Provider/FileProvider.php | 20 +- .../ObjectStorage/Provider/RedisProvider.php | 188 +++++++++++++++ .../ObjectStorage/iObjectStorageProvider.php | 5 +- test/base/ObjectStorageCacheTest.php | 198 ++++++++++++++++ test/base/ObjectStorageProviderTest.php | 216 ++++++++++++++++++ test/bootstrap.php | 15 +- .../config.objectstorage.php | 26 ++- test/phpunit.xml | 17 ++ 13 files changed, 993 insertions(+), 31 deletions(-) delete mode 100644 .drone.yml create mode 100644 src/FuzeWorks/ObjectStorage/ObjectStorageCache.php create mode 100644 src/FuzeWorks/ObjectStorage/Provider/DummyProvider.php create mode 100644 src/FuzeWorks/ObjectStorage/Provider/RedisProvider.php create mode 100644 test/base/ObjectStorageCacheTest.php create mode 100644 test/base/ObjectStorageProviderTest.php rename config.storage.php => test/config.objectstorage.php (54%) create mode 100644 test/phpunit.xml diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index e69de29..0000000 diff --git a/.gitignore b/.gitignore index c6f4d6e..daa97e5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ composer.phar .idea/ build/ test/temp/ -vendor/ \ No newline at end of file +vendor/ +/test/.phpunit.result.cache diff --git a/src/FuzeWorks/ObjectStorage/ObjectStorageCache.php b/src/FuzeWorks/ObjectStorage/ObjectStorageCache.php new file mode 100644 index 0000000..e4822f2 --- /dev/null +++ b/src/FuzeWorks/ObjectStorage/ObjectStorageCache.php @@ -0,0 +1,128 @@ +provider = $provider; + } + + private function testTTL(string $key) + { + $meta = $this->provider->getItemMeta('fwcache_' . $key); + if ($meta['ttl'] > 0 && time() > $meta['time'] + $meta['ttl']) + $this->provider->deleteItem('fwcache_' . $key); + } + + public function get($key, $default = null) + { + // Remove the item if its TTL has expired + $this->testTTL($key); + + // Fetch the value + $res = $this->provider->getItem('fwcache_' . $key); + + // If there is no value, return the default + return is_null($res) ? $default : $res; + } + + public function set($key, $value, $ttl = null) + { + $meta = [ + 'time' => time(), + 'ttl' => is_int($ttl) ? $ttl : 0 + ]; + + return $this->provider->save('fwcache_' . $key, $value, $meta); + } + + public function delete($key) + { + return $this->provider->deleteItem('fwcache_' . $key); + } + + public function clear() + { + // Fetch the index set + $index = $this->provider->getIndex(); + foreach ($index as $entry) + { + if (substr($entry, 0, 8) === 'fwcache_') + $this->provider->deleteItem($entry); + } + + return true; + } + + public function getMultiple($keys, $default = null) + { + $out = []; + foreach ($keys as $key) + { + $out[$key] = $this->get($key, $default); + } + + return $out; + } + + public function setMultiple($values, $ttl = null) + { + foreach ($values as $key => $value) + $this->set($key, $value, $ttl); + + return true; + } + + public function deleteMultiple($keys) + { + foreach ($keys as $key) + $this->delete($key); + + return true; + } + + public function has($key) + { + $this->testTTL($key); + return $this->provider->hasItem('fwcache_' . $key); + } +} \ No newline at end of file diff --git a/src/FuzeWorks/ObjectStorage/ObjectStorageComponent.php b/src/FuzeWorks/ObjectStorage/ObjectStorageComponent.php index 0c35e21..0934535 100644 --- a/src/FuzeWorks/ObjectStorage/ObjectStorageComponent.php +++ b/src/FuzeWorks/ObjectStorage/ObjectStorageComponent.php @@ -34,9 +34,14 @@ */ namespace FuzeWorks\ObjectStorage; +use FuzeWorks\Config; use FuzeWorks\Configurator; +use FuzeWorks\Exception\ConfigException; +use FuzeWorks\Exception\FactoryException; use FuzeWorks\Factory; use FuzeWorks\iComponent; +use FuzeWorks\ObjectStorage\Exception\ObjectStorageException; +use Psr\SimpleCache\CacheInterface; /** * ObjectStorageComponent Class. @@ -49,6 +54,27 @@ use FuzeWorks\iComponent; class ObjectStorageComponent implements iComponent { + /** + * The configuration file for ObjectStorage + * + * @var array + */ + private array $cfg; + + /** + * The currently selected ObjectStorageProvider + * + * @var iObjectStorageProvider + */ + private iObjectStorageProvider $provider; + + /** + * The currently used CacheInterface + * + * @var CacheInterface + */ + private CacheInterface $cache; + public function getName(): string { return 'ObjectStorageComponent'; @@ -59,6 +85,71 @@ class ObjectStorageComponent implements iComponent return ['storage' => $this]; } + /** + * Fetches and returns the currently selected ObjectStorageProvider + * + * @throws ObjectStorageException + * @return iObjectStorageProvider + */ + public function getStorage(): iObjectStorageProvider + { + // If the provider is already loaded, return that one + if (isset($this->provider)) + return $this->provider; + + // Load the config, if it isn't loaded yet + if (!isset($this->cfg)) + { + try { + /** @var Config $configs */ + $configs = Factory::getInstance('config'); + $this->cfg = $configs->getConfig('objectstorage')->toArray(); + } catch (ConfigException | FactoryException $e) { + throw new ObjectStorageException("Could not get ObjectStorageProvider. No config file named 'config.objectstorage.php' could be found."); + } + } + + // Get the currently selected ObjectStorageProvider + $selected = $this->cfg['ObjectStorageProvider']; + if (is_null($selected)) + throw new ObjectStorageException("Could not get ObjectStorageProvider. Selected provider is null!"); + + // Try and load the ObjectStorageProvider + $class = '\FuzeWorks\ObjectStorage\Provider\\' . $selected; + if (!class_exists($class, true)) + throw new ObjectStorageException("Could not get ObjectStorageProvider. Selected provider '".$selected."' is not recognized."); + + /** @var iObjectStorageProvider $provider */ + $provider = new $class(); + if (!$provider instanceof iObjectStorageProvider) + throw new ObjectStorageException("Could not get ObjectStorageProvider. Selected provider '".$selected."' is not an instance of iObjectStorageProvider'."); + + // Fetch the parameters + $params = isset($this->cfg[$selected]) && is_array($this->cfg[$selected]) ? $this->cfg[$selected] : []; + if (!$provider->init($params)) + throw new ObjectStorageException("Could not get ObjectStorageProvider. Selected provider '".$selected."' failed to load."); + + $this->provider = $provider; + return $this->provider; + } + + /** + * Returns a PSR compatible Cache object + * + * @return CacheInterface + * @throws ObjectStorageException + */ + public function getCache(): CacheInterface + { + if (isset($this->cache)) + return $this->cache; + + $storageProvider = $this->getStorage(); + $this->cache = new ObjectStorageCache($storageProvider); + + return $this->cache; + } + public function onAddComponent(Configurator $configurator) { } diff --git a/src/FuzeWorks/ObjectStorage/Provider/DummyProvider.php b/src/FuzeWorks/ObjectStorage/Provider/DummyProvider.php new file mode 100644 index 0000000..4face6c --- /dev/null +++ b/src/FuzeWorks/ObjectStorage/Provider/DummyProvider.php @@ -0,0 +1,117 @@ + [], 'data' => []]; + + public function init(array $providerConfig): bool + { + return true; + } + + public function getIndex(): array + { + return $this->data['index']; + } + + public function getItem(string $key) + { + if (!in_array($key, $this->data['index'])) + return null; + + return $this->data['data'][$key]['data']; + } + + public function getItemMeta(string $key): ?array + { + if (!in_array($key, $this->data['index'])) + return null; + + return $this->data['data'][$key]['meta']; + } + + public function getItems(array $keys = []): array + { + $output = []; + foreach ($keys as $key) + $output[$key] = $this->getItem($key); + + return $output; + } + + public function hasItem(string $key): bool + { + return in_array($key, $this->data['index']); + } + + public function clear(): bool + { + return $this->deleteItems($this->getIndex()); + } + + public function deleteItem(string $key): bool + { + // Remove the index + if (($k = array_search($key, $this->data['index'])) !== false) { + unset($this->data['index'][$k]); + } + + // And remove the data + unset($this->data['data'][$key]); + return true; + } + + public function deleteItems(array $keys): bool + { + foreach ($keys as $key) + $this->deleteItem($key); + + return true; + } + + public function save(string $key, $value, array $metaData = []): bool + { + if (!in_array($key, $this->data['index'])) + $this->data['index'][] = $key; + + $this->data['data'][$key] = ['data' => $value, 'meta' => $metaData]; + return true; + } +} \ No newline at end of file diff --git a/src/FuzeWorks/ObjectStorage/Provider/FileProvider.php b/src/FuzeWorks/ObjectStorage/Provider/FileProvider.php index 0dd287d..5d76ef2 100644 --- a/src/FuzeWorks/ObjectStorage/Provider/FileProvider.php +++ b/src/FuzeWorks/ObjectStorage/Provider/FileProvider.php @@ -83,7 +83,7 @@ class FileProvider implements iObjectStorageProvider public function init(array $providerConfig): bool { // First load the directory from the providerConfig - $directory = isset($providerConfig['storageDirectory']) ? $providerConfig['storageDirectory'] : null; + $directory = isset($providerConfig['storage_directory']) ? $providerConfig['storage_directory'] : null; // Check if the directory exists if (!file_exists($directory) || !is_dir($directory)) @@ -117,7 +117,7 @@ class FileProvider implements iObjectStorageProvider return $this->index; } - public function getItem(string $key): ?array + public function getItem(string $key) { // Convert the key $file = $this->directory . DS . crc32($key) . '.fwstorage'; @@ -134,11 +134,7 @@ class FileProvider implements iObjectStorageProvider } // Otherwise try and load the metaData and contents - $meta = $this->index[$key]['meta']; - $data = unserialize(file_get_contents($file)); - - // Return the combined data - return ['meta' => $meta, 'data' => $data]; + return unserialize(file_get_contents($file)); } public function getItemMeta(string $key): ?array @@ -218,16 +214,6 @@ class FileProvider implements iObjectStorageProvider return false; } - public function commit(): bool - { - // TODO: Implement commit() method. - } - - public function revert(): bool - { - // TODO: Implement revert() method. - } - private function commitIndex(): bool { if ($this->write_file($this->indexFile, serialize(['index' => $this->index]))) { diff --git a/src/FuzeWorks/ObjectStorage/Provider/RedisProvider.php b/src/FuzeWorks/ObjectStorage/Provider/RedisProvider.php new file mode 100644 index 0000000..95e2e34 --- /dev/null +++ b/src/FuzeWorks/ObjectStorage/Provider/RedisProvider.php @@ -0,0 +1,188 @@ +conn = new Redis(); + + // Afterwards we attempt to connect to the server + $socketType = $providerConfig['socket_type']; + if ($socketType === 'unix') + $success = $this->conn->connect($providerConfig['socket']); + elseif ($socketType === 'tcp') + $success = $this->conn->connect($providerConfig['host'], $providerConfig['port'], $providerConfig['timeout']); + else + $success = false; + + // If failed, throw an exception informing so + if (!$success) + throw new ObjectStorageException("Could not load RedisProvider ObjectStorage. Unable to connect to server."); + + // If authentication is required, attempt to do so with the provided password + if (isset($providerConfig['password']) && !$this->conn->auth($providerConfig['password'])) + throw new ObjectStorageException("Could not load RedisProvider ObjectStorage. Authentication failure."); + + // If a db_index is provided, use that one accordingly + if (isset($providerConfig['db_index']) && is_int($providerConfig['db_index'])) + $this->conn->select($providerConfig['db_index']); + + // And if all goes well, report a true + return true; + + // If any sort of failure has occurred along the way, + } catch (RedisException $e) { + throw new ObjectStorageException("Could not load RedisProvider ObjectStorage. RedisException thrown: '" . $e->getMessage() . "'"); + } + } + + public function getIndex(): array + { + return $this->conn->sMembers('ObjectStorageIndex'); + } + + public function getItem(string $key) + { + // If the requested key is not part of the index, this item is not tracked and should therefore + // return null. + if (!$this->conn->sIsMember('ObjectStorageIndex', $key)) + return null; + + // If the data doesn't exist, return null + if (!$this->conn->hExists('fwstorage_' . $key, 'data')) + return null; + + return unserialize($this->conn->hGet('fwstorage_' . $key, 'data')); + } + + public function getItemMeta(string $key): ?array + { + // If the requested key is not part of the index, this item is not tracked and should therefore + // return null. + if (!$this->conn->sIsMember('ObjectStorageIndex', $key)) + return null; + + // If the data doesn't exist, return null + if (!$this->conn->hExists('fwstorage_' . $key, 'meta')) + return null; + + return unserialize($this->conn->hGet('fwstorage_' . $key, 'meta')); + } + + public function getItems(array $keys = []): array + { + $output = []; + foreach ($keys as $key) + $output[$key] = $this->getItem($key); + + return $output; + } + + public function hasItem(string $key): bool + { + return $this->conn->sIsMember('ObjectStorageIndex', $key); + } + + public function clear(): bool + { + return $this->deleteItems($this->getIndex()); + } + + public function deleteItem(string $key): bool + { + // If the requested key is not part of the index, this item is not tracked and should therefore + // return null. + if ($this->conn->sIsMember('ObjectStorageIndex', $key)) + $this->conn->sRem('ObjectStorageIndex', $key); + + if ($this->conn->exists('fwstorage_' . $key)) + $this->conn->del('fwstorage_' . $key); + + return true; + } + + public function deleteItems(array $keys): bool + { + foreach ($keys as $key) + $this->deleteItem($key); + + return true; + } + + public function save(string $key, $value, array $metaData = []): bool + { + // If the requested key is not part of the index, this item is not tracked and should therefore + // return null. + if (!$this->conn->sIsMember('ObjectStorageIndex', $key)) + $this->conn->sAdd('ObjectStorageIndex', $key); + + // Write to the hash + $this->conn->hSet('fwstorage_' . $key, 'data', serialize($value)); + $this->conn->hSet('fwstorage_' . $key, 'meta', serialize($metaData)); + + return true; + } +} \ No newline at end of file diff --git a/src/FuzeWorks/ObjectStorage/iObjectStorageProvider.php b/src/FuzeWorks/ObjectStorage/iObjectStorageProvider.php index 8000a0f..2504dcf 100644 --- a/src/FuzeWorks/ObjectStorage/iObjectStorageProvider.php +++ b/src/FuzeWorks/ObjectStorage/iObjectStorageProvider.php @@ -34,7 +34,6 @@ */ namespace FuzeWorks\ObjectStorage; -use Traversable; interface iObjectStorageProvider { @@ -42,7 +41,7 @@ interface iObjectStorageProvider public function init(array $providerConfig): bool; public function getIndex(): array; - public function getItem(string $key): ?array; + public function getItem(string $key); public function getItemMeta(string $key): ?array; public function getItems(array $keys = []): array; public function hasItem(string $key): bool; @@ -50,7 +49,5 @@ interface iObjectStorageProvider public function deleteItem(string $key): bool; public function deleteItems(array $keys): bool; public function save(string $key, $value, array $metaData = []): bool; - public function commit(): bool; - public function revert(): bool; } \ No newline at end of file diff --git a/test/base/ObjectStorageCacheTest.php b/test/base/ObjectStorageCacheTest.php new file mode 100644 index 0000000..578ede6 --- /dev/null +++ b/test/base/ObjectStorageCacheTest.php @@ -0,0 +1,198 @@ +loadProvider(); + } + + public function tearDown(): void + { + parent::tearDown(); + + // Always clear the cache after every test + $this->cache->clear(); + } + + private function loadProvider() + { + /** @var ObjectStorageComponent $objectStorageComponent */ + $objectStorageComponent = Factory::getInstance('storage'); + $this->cache = $objectStorageComponent->getCache(); + } + + public function testFoundation() + { + $this->assertInstanceOf('\Psr\SimpleCache\CacheInterface', $this->cache); + $this->assertInstanceOf('\FuzeWorks\ObjectStorage\ObjectStorageCache', $this->cache); + } + + /** + * @depends testFoundation + */ + public function testSetGetAndHas() + { + $testData = ['hello', 'world']; + + // First check the data isn't there + $this->assertFalse($this->cache->has('testData')); + + // Then write it + $this->assertTrue($this->cache->set('testData', $testData)); + + // Assert it is there and check its contents + $this->assertTrue($this->cache->has('testData')); + $this->assertEquals(['hello', 'world'], $this->cache->get('testData')); + } + + /** + * @depends testSetGetAndHas + */ + public function testGetDefaultValue() + { + // Verify that no value exists + $this->assertFalse($this->cache->has('testData')); + $this->assertNull($this->cache->get('testData')); + + // And check if the default value is returned + $this->assertEquals('default!', $this->cache->get('testData', 'default!')); + } + + /** + * @depends testSetGetAndHas + */ + public function testDeleteValue() + { + // Verify that none exist + $this->assertFalse($this->cache->has('testData')); + + // Write some data + $this->assertTrue($this->cache->set('testData', 'someValue')); + $this->assertEquals('someValue', $this->cache->get('testData')); + $this->assertTrue($this->cache->has('testData')); + + // Delete it + $this->assertTrue($this->cache->delete('testData')); + $this->assertFalse($this->cache->has('testData')); + } + + /** + * @depends testDeleteValue + */ + public function testClear() + { + // Write some data + $this->assertTrue($this->cache->set('testData1', 'value1')); + $this->assertTrue($this->cache->set('testData2', 'value2')); + + // Then clear it off + $this->assertTrue($this->cache->clear()); + $this->assertFalse($this->cache->has('testData1')); + $this->assertFalse($this->cache->has('testData2')); + } + + /** + * @depends testDeleteValue + */ + public function testMultiple() + { + // First check that none of the variables exist + $this->assertFalse($this->cache->has('testData1')); + $this->assertFalse($this->cache->has('testData2')); + $this->assertFalse($this->cache->has('testData3')); + + // With a get multiple, and default + $this->assertEquals([ + 'testData1' => 'default', + 'testData2' => 'default', + 'testData3' => 'default' + ], $this->cache->getMultiple(['testData1', 'testData2', 'testData3'], 'default')); + + // Write multiple + $this->assertTrue($this->cache->setMultiple([ + 'testData1' => 'value1', + 'testData2' => 'value2', + 'testData3' => 'value3' + ])); + + // Test the contents + $this->assertEquals([ + 'testData1' => 'value1', + 'testData2' => 'value2', + 'testData3' => 'value3' + ], $this->cache->getMultiple(['testData1', 'testData2', 'testData3'], 'default')); + + // And also delete them all + $this->assertTrue($this->cache->deleteMultiple(['testData1', 'testData2', 'testData3'])); + $this->assertFalse($this->cache->has('testData1')); + $this->assertFalse($this->cache->has('testData2')); + $this->assertFalse($this->cache->has('testData3')); + } + + /** + * @depends testSetGetAndHas + */ + public function testTTL() + { + $testData = ['hello', 'world']; + + // First check the data isn't there + $this->assertFalse($this->cache->has('testData')); + + // Then write it + $this->assertTrue($this->cache->set('testData', $testData, 1)); + + // Assert it is there and check its contents + $this->assertTrue($this->cache->has('testData')); + $this->assertEquals(['hello', 'world'], $this->cache->get('testData')); + + // Then wait 2 secs + sleep(2); + + // And check again + $this->assertFalse($this->cache->has('testData')); + } +} \ No newline at end of file diff --git a/test/base/ObjectStorageProviderTest.php b/test/base/ObjectStorageProviderTest.php new file mode 100644 index 0000000..3246df5 --- /dev/null +++ b/test/base/ObjectStorageProviderTest.php @@ -0,0 +1,216 @@ +loadProvider(); + } + + public function tearDown(): void + { + parent::tearDown(); // TODO: Change the autogenerated stub + + // Always clear the provider at the end + $this->provider->clear(); + } + + private function loadProvider() + { + /** @var ObjectStorageComponent $objectStorageComponent */ + $objectStorageComponent = Factory::getInstance('storage'); + $this->provider = $objectStorageComponent->getStorage(); + } + + public function testFoundation() + { + $this->assertInstanceOf('\FuzeWorks\ObjectStorage\iObjectStorageProvider', $this->provider); + } + + /** + * @depends testFoundation + */ + public function testSave() + { + $testData = ['hello', 'world', 'foo' => 'bar']; + + // First assert it does not exist yet + $this->assertNull($this->provider->getItem('testData')); + $this->assertFalse($this->provider->hasItem('testData')); + + // Write the data + $this->assertTrue($this->provider->save('testData', $testData)); + + // Read the data + $this->assertTrue($this->provider->hasItem('testData')); + $this->assertEquals(['hello', 'world', 'foo' => 'bar'], $this->provider->getItem('testData')); + } + + /** + * @depends testSave + */ + public function testDeleteItem() + { + $testData = ['o', 'm', 'g']; + + // First assert that the data does not exist yet + $this->assertNull($this->provider->getItem('testDeleteData')); + + // Write the data + $this->assertTrue($this->provider->save('testDeleteData', $testData)); + + // Read the data + $this->assertEquals(['o', 'm', 'g'], $this->provider->getItem('testDeleteData')); + + // Delete the data + $this->assertTrue($this->provider->deleteItem('testDeleteData')); + + // And test that it is truly gone + $this->assertNull($this->provider->getItem('testDeleteData')); + } + + /** + * @depends testDeleteItem + */ + public function testDeleteItems() + { + $testData = 'lord'; + $testData2 = 'almighty'; + + // First assert that the data does not exist yet + $this->assertNull($this->provider->getItem('testDeleteData1')); + $this->assertNull($this->provider->getItem('testDeleteData2')); + + // Write the data + $this->assertTrue($this->provider->save('testDeleteData1', $testData)); + $this->assertTrue($this->provider->save('testDeleteData2', $testData2)); + + // Read the data + $this->assertEquals( + ['testDeleteData1' => 'lord', 'testDeleteData2' => 'almighty'], + $this->provider->getItems(['testDeleteData1', 'testDeleteData2']) + ); + + // Delete the data + $this->assertTrue($this->provider->deleteItems(['testDeleteData1', 'testDeleteData2'])); + + // And test that it is truly gone + $this->assertNull($this->provider->getItem('testDeleteData1')); + $this->assertNull($this->provider->getItem('testDeleteData2')); + } + + /** + * @depends testDeleteItems + */ + public function testClear() + { + $testData = ['not', 'my', 'department']; + + // First assert it does not exist yet + $this->assertNull($this->provider->getItem('testClearData')); + + $this->provider->save('testClearData', $testData); + + // Test that it can be read + $this->assertEquals(['not', 'my', 'department'], $this->provider->getItem('testClearData')); + + // Then attempt to clean it + $this->assertTrue($this->provider->clear()); + + // And check that it cannot be read + $this->assertNull($this->provider->getItem('testClearData')); + } + + public function testItemNotExist() + { + $this->assertNull($this->provider->getItem('doesNotExist')); + } + + public function testGetMultipleItems() + { + $testData1 = ['tao', 'te', 'ching']; + $testData2 = ['plato', 'aristotle']; + + // First assert they do not exist + $this->assertNull($this->provider->getItem('philo1')); + $this->assertNull($this->provider->getItem('philo2')); + $this->assertEquals(['philo1' => null, 'philo2' => null], $this->provider->getItems(['philo1', 'philo2'])); + + // Then write both + $this->assertTrue($this->provider->save('philo1', $testData1)); + $this->assertTrue($this->provider->save('philo2', $testData2)); + + // Then read + $this->assertEquals([ + 'philo1' => ['tao', 'te', 'ching'], + 'philo2' => ['plato', 'aristotle'] + ], $this->provider->getItems(['philo1', 'philo2'])); + } + + public function testItemMetaData() + { + $testData = ['meine', 'gute']; + $metaData = ['someKey' => 'someValue']; + + // First assert that the data does not exist + $this->assertNull($this->provider->getItem('testData')); + $this->assertNull($this->provider->getItemMeta('testData')); + + // Then save the data + $this->assertTrue($this->provider->save('testData', $testData, $metaData)); + + // Check the metaData + $this->assertEquals(['someKey' => 'someValue'], $this->provider->getItemMeta('testData')); + + // Remove the key + $this->provider->deleteItem('testData'); + $this->assertNull($this->provider->getItemMeta('testData')); + } +} \ No newline at end of file diff --git a/test/bootstrap.php b/test/bootstrap.php index ae6f478..9bd0d20 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -32,9 +32,13 @@ * * @version Version 1.3.0 */ + require_once(dirname(__DIR__) . '/vendor/autoload.php'); -$configurator = new \FuzeWorks\Configurator(); +use FuzeWorks\Configurator; +use FuzeWorks\Priority; + +$configurator = new Configurator(); // Set directories $configurator->setTempDirectory(__DIR__ . '/temp'); @@ -43,15 +47,10 @@ $configurator->setLogDirectory(__DIR__ . '/temp'); // Other values $configurator->setTimeZone('Europe/Amsterdam'); -// Add TracyComponent -\FuzeWorks\TracyComponent::enableTracy(); -$configurator->addComponent(new \FuzeWorks\TracyComponent()); - // And the star of the show: ObjectStorageComponent $configurator->addComponent(new \FuzeWorks\ObjectStorage\ObjectStorageComponent()); -// Debug related -$configurator->enableDebugMode(); -$configurator->setDebugAddress('ALL'); +// Add the test config file +$configurator->addDirectory(dirname(__FILE__), 'config', Priority::HIGH); return $configurator->createContainer(); \ No newline at end of file diff --git a/config.storage.php b/test/config.objectstorage.php similarity index 54% rename from config.storage.php rename to test/config.objectstorage.php index 8c2d911..ecbcb2a 100644 --- a/config.storage.php +++ b/test/config.objectstorage.php @@ -33,4 +33,28 @@ * @version Version 1.3.0 */ -return []; \ No newline at end of file +use FuzeWorks\Core; + +return [ + // Which provider shall be used + // Options: DummyProvider, RedisProvider, FileProvider + 'ObjectStorageProvider' => Core::getEnv('OBJECTSTORAGE_PROVIDER', null), + 'DummyProvider' => [], + 'RedisProvider' => [ + // Type can be 'tcp' or 'unix' + 'socket_type' => Core::getEnv('OBJECTSTORAGE_REDIS_SOCKET_TYPE', 'tcp'), + // If socket_type == 'unix', set the socket here + 'socket' => Core::getEnv('OBJECTSTORAGE_REDIS_SOCKET', null), + // If socket_type == 'tcp', set the host here + 'host' => Core::getEnv('OBJECTSTORAGE_REDIS_HOST', '127.0.0.1'), + // And some standard settings + 'port' => Core::getEnv('OBJECTSTORAGE_REDIS_PORT', 6379), + 'password' => Core::getEnv('OBJECTSTORAGE_REDIS_PASSWORD', null), + 'timeout' => Core::getEnv('OBJECTSTORAGE_REDIS_TIMEOUT', 0), + 'db_index' => Core::getEnv('OBJECTSTORAGE_REDIS_DBINDEX', 0), + ], + 'FileProvider' => [ + // The directory where objects get stored by the FileProvider + 'storage_directory' => Core::getEnv('OBJECTSTORAGE_FILE_DIRECTORY', Core::$tempDir) + ] +]; \ No newline at end of file diff --git a/test/phpunit.xml b/test/phpunit.xml new file mode 100644 index 0000000..d4c77a6 --- /dev/null +++ b/test/phpunit.xml @@ -0,0 +1,17 @@ + + + + + ../ + + + ../vendor/ + ../test/ + + + + + ./ + + +