Skip to content

Commit

Permalink
Merge pull request #9 from shadowhand/feature/redis-adapter
Browse files Browse the repository at this point in the history
Add Redis storage adapter
  • Loading branch information
richardfullmer committed Oct 27, 2015
2 parents 39ad702 + ff49439 commit 41a2afe
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 3 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@ Storage
There are a number of different storage implementations for where the configuration for the rollout is stored.

* ArrayStorage - default storage, not persistent
* DoctrineCacheStorageAdapter - requires `doctrine/cache`
* PDOStorageAdapter - persistent with a simple \PDO object
* DoctrineCacheStorageAdapter - requires [doctrine/cache][doctrine-cache]
* PDOStorageAdapter - persistent using [PDO][pdo]
* RedisStorageAdapter - persistent using [Redis][redis]

The storage implementation must implement the `Storage\StorageInterface`'s methods.
[doctrine-cache]: https://packagist.org/packages/doctrine/cache
[pdo]: http://php.net/pdo
[redis]: http://redis.io

All storage adapters must implement `Opensoft\Rollout\Storage\StorageInterface`.

Groups
------
Expand Down
4 changes: 4 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@
</whitelist>
</filter>

<logging>
<log type="coverage-text" target="php://stdout"/>
</logging>

</phpunit>
63 changes: 63 additions & 0 deletions src/Storage/RedisStorageAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Opensoft\Rollout\Storage;

/**
* Storage adapter using Redis
*
* @author Woody Gilk <@shadowhand>
*/
class RedisStorageAdapter implements StorageInterface
{
/**
* @var string
*/
const DEFAULT_GROUP = 'rollout_feature';

/**
* @var object
*/
private $redis;

/**
* @var string
*/
private $group = self::DEFAULT_GROUP;

public function __construct($redis, $group = null)
{
$this->redis = $redis;

if ($group) {
$this->group = $group;
}
}

/**
* @inheritdoc
*/
public function get($key)
{
$result = $this->redis->hget($this->group, $key);

if (empty($result)) {
return null;
}

$result = json_decode($result, true);

if (JSON_ERROR_NONE !== json_last_error()) {
return null;
}

return $result;
}

/**
* @inheritdoc
*/
public function set($key, $value)
{
$this->redis->hset($this->group, $key, json_encode($value));
}
}
95 changes: 95 additions & 0 deletions tests/Storage/RedisStorageAdapterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace Opensoft\Tests\Storage;

use Opensoft\Rollout\Storage\RedisStorageAdapter;

class RedisStorageAdapterTest extends \PHPUnit_Framework_TestCase
{
private $redis;

public function setUp()
{
$this->redis = $this->getMockBuilder('\Opensoft\Tests\Storage\mockRedis')->getMock();
}

public function testGet()
{
$this->redis->expects($this->once())
->method('hget')
->with(RedisStorageAdapter::DEFAULT_GROUP, 'key')
->willReturn(json_encode('success'));

$adapter = new RedisStorageAdapter($this->redis);

$result = $adapter->get('key');
$this->assertSame('success', $result);
}

public function testGetWithCustomGroup()
{
$this->redis->expects($this->once())
->method('hget')
->with('rollout_test', 'key')
->willReturn(json_encode('success'));

$adapter = new RedisStorageAdapter($this->redis, 'rollout_test');

$result = $adapter->get('key');
$this->assertSame('success', $result);
}

public function testGetNotExistsFailure()
{
$this->redis->expects($this->once())
->method('hget')
->with(RedisStorageAdapter::DEFAULT_GROUP, 'key')
->willReturn('');

$adapter = new RedisStorageAdapter($this->redis);

$result = $adapter->get('key');
$this->assertNull($result);
}

public function testGetJsonDecodeFailure()
{
$this->redis->expects($this->once())
->method('hget')
->with(RedisStorageAdapter::DEFAULT_GROUP, 'key')
->willReturn('not json');

$adapter = new RedisStorageAdapter($this->redis);

$result = $adapter->get('key');
$this->assertNull($result);
}

public function testSet()
{
$this->redis->expects($this->once())
->method('hset')
->with(RedisStorageAdapter::DEFAULT_GROUP, 'key', json_encode('value'));

$adapter = new RedisStorageAdapter($this->redis);

$adapter->set('key', 'value');
}

public function testSetWithCustomGroup()
{
$this->redis->expects($this->once())
->method('hset')
->with('rollout_test', 'key', json_encode('value'));

$adapter = new RedisStorageAdapter($this->redis, 'rollout_test');

$adapter->set('key', 'value');
}
}

interface mockRedis
{
public function hget($key, $field);
public function hset($key, $field, $value);
}

0 comments on commit 41a2afe

Please sign in to comment.