Skip to content

Commit

Permalink
Add support for Lumen 5.4+
Browse files Browse the repository at this point in the history
Signed-off-by: Cy Rossignol <[email protected]>
  • Loading branch information
cyrossignol committed Sep 3, 2017
1 parent 2e5e26d commit 70dbe1d
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 39 deletions.
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "monospice/laravel-redis-sentinel-drivers",
"description": "Laravel configuration wrapper for highly-available Redis Sentinel replication.",
"keywords": ["redis", "sentinel", "laravel"],
"description": "Redis Sentinel integration for Laravel and Lumen.",
"keywords": ["redis", "sentinel", "laravel", "lumen"],
"type": "library",
"license": "MIT",
"authors": [
Expand All @@ -13,6 +13,7 @@
"require": {
"php": ">=5.6.4",
"illuminate/cache": "^5.4",
"illuminate/contracts": "^5.4",
"illuminate/queue": "^5.4",
"illuminate/redis": "^5.4",
"illuminate/session": "^5.4",
Expand All @@ -22,6 +23,7 @@
},
"require-dev": {
"laravel/framework": "^5.4",
"laravel/lumen-framework": "^5.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "^4.8"
},
Expand Down
60 changes: 49 additions & 11 deletions src/RedisSentinelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Illuminate\Cache\CacheManager;
use Illuminate\Cache\RedisStore;
use Illuminate\Foundation\Application;
use Illuminate\Queue\QueueManager;
use Illuminate\Queue\Connectors\RedisConnector;
use Illuminate\Session\CacheBasedSessionHandler;
Expand Down Expand Up @@ -35,18 +34,18 @@ class RedisSentinelServiceProvider extends ServiceProvider
public function boot()
{
$this->addRedisSentinelCacheDriver($this->app->make('cache'));
$this->addRedisSentinelSessionHandler($this->app->make('session'));
$this->addRedisSentinelQueueConnector($this->app->make('queue'));

// Lumen removed session support since version 5.2, so we'll only bind
// the Sentinel session handler if we're running Laravel.
if (! $this->isLumenApplication()) {
$this->addRedisSentinelSessionHandler($this->app->make('session'));
}

// If we want Laravel's Redis API to use Sentinel, we'll remove the
// "redis" service from the list of deferred services in the container:
if ($this->shouldOverrideLaravelApi()) {
$deferredServices = $this->app->getDeferredServices();

unset($deferredServices['redis']);
unset($deferredServices['redis.connection']);

$this->app->setDeferredServices($deferredServices);
$this->removeDeferredRedisServices();
}
}

Expand Down Expand Up @@ -77,7 +76,7 @@ public function register()

/**
* Replace the standard Laravel Redis service with the Redis Sentinel
* database driver so all redis operations use Sentinel connections.
* database driver so all Redis operations use Sentinel connections.
*
* @return void
*/
Expand All @@ -92,6 +91,26 @@ protected function registerOverrides()
});
}

/**
* Remove the standard Laravel Redis service from the bound deferred
* services so they don't overwrite Redis Sentinel registrations.
*
* @return void
*/
protected function removeDeferredRedisServices()
{
if ($this->isLumenApplication()) {
return;
}

$deferredServices = $this->app->getDeferredServices();

unset($deferredServices['redis']);
unset($deferredServices['redis.connection']);

$this->app->setDeferredServices($deferredServices);
}

/**
* Add "redis-sentinel" as an available driver option to the Laravel cache
* manager.
Expand Down Expand Up @@ -168,17 +187,36 @@ protected function shouldOverrideLaravelApi()

/**
* Get the fully-qualified class name of the RedisSentinelManager class
* for the current version of Laravel.
* for the current version of Laravel or Lumen.
*
* @return string The class name of the appropriate RedisSentinelManager
* with its namespace
*/
protected function getVersionedRedisSentinelManagerClass()
{
if (version_compare(Application::VERSION, '5.4.20', 'lt')) {
if ($this->isLumenApplication()) {
$appVersion = substr($this->app->version(), 7, 3);
$frameworkVersion = '5.4';
} else {
$appVersion = \Illuminate\Foundation\Application::VERSION;
$frameworkVersion = '5.4.20';
}

if (version_compare($appVersion, $frameworkVersion, 'lt')) {
return Manager\Laravel540RedisSentinelManager::class;
}

return Manager\Laravel5420RedisSentinelManager::class;
}

/**
* Determine if the current application runs the Lumen framework instead of
* Laravel.
*
* @return bool True if running Lumen
*/
protected function isLumenApplication()
{
return $this->app instanceof \Laravel\Lumen\Application;
}
}
14 changes: 12 additions & 2 deletions tests/RedisSentinelFacadeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@

namespace Monospice\LaravelRedisSentinel\Tests;

use Illuminate\Foundation\Application;
use Mockery;
use Monospice\LaravelRedisSentinel\RedisSentinel;
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
use Monospice\LaravelRedisSentinel\Tests\Support\ApplicationFactory;
use PHPUnit_Framework_TestCase as TestCase;

class RedisSentinelFacadeTest extends TestCase
{
/**
* Run this cleanup after each test.
*
* @return void
*/
public function tearDown()
{
Mockery::close();
}

public function testResolvesFacadeServiceFromContainer()
{
$service = RedisSentinelManager::class;
$app = ApplicationFactory::make();

$app = new Application();
$app->singleton('redis-sentinel', function () use ($service) {
return Mockery::mock($service);
});
Expand Down
10 changes: 10 additions & 0 deletions tests/RedisSentinelManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ public function setUp()
$this->manager = new RedisSentinelManager($this->versionedManagerMock);
}

/**
* Run this cleanup after each test.
*
* @return void
*/
public function tearDown()
{
Mockery::close();
}

public function testIsInitializable()
{
$this->assertInstanceOf(RedisSentinelManager::class, $this->manager);
Expand Down
28 changes: 11 additions & 17 deletions tests/RedisSentinelServiceProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,20 @@

namespace Monospice\LaravelRedisSentinel\Tests;

use Illuminate\Cache\CacheServiceProvider;
use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Contracts\Redis\Factory as RedisFactory;
use Illuminate\Foundation\Application;
use Illuminate\Queue\QueueServiceProvider;
use Illuminate\Redis\RedisManager;
use Illuminate\Redis\RedisServiceProvider;
use Illuminate\Session\SessionServiceProvider;
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
use Monospice\LaravelRedisSentinel\RedisSentinelServiceProvider;
use Monospice\LaravelRedisSentinel\Tests\Support\ApplicationFactory;
use PHPUnit_Framework_TestCase as TestCase;

class RedisSentinelServiceProviderTest extends TestCase
{
/**
* An instance of the Laravel application container
* An instance of the Laravel or Lumen application container.
*
* @var Application
* @var \Illuminate\Contracts\Container\Container
*/
protected $app;

Expand All @@ -37,16 +33,9 @@ class RedisSentinelServiceProviderTest extends TestCase
*/
public function setUp()
{
$this->app = new Application();
$this->app = ApplicationFactory::make();

$this->app->config = new ConfigRepository(
require(__DIR__ . '/stubs/config.php')
);

$this->app->register(new CacheServiceProvider($this->app));
$this->app->register(new QueueServiceProvider($this->app));
$this->app->register(new RedisServiceProvider($this->app));
$this->app->register(new SessionServiceProvider($this->app));
$this->app->config->set(require(__DIR__ . '/stubs/config.php'));

$this->provider = new RedisSentinelServiceProvider($this->app);
}
Expand Down Expand Up @@ -83,6 +72,7 @@ public function testRegisterPreservesStandardRedisApi()

public function testRegisterOverridesStandardRedisApi()
{
$this->app->config->set('database.redis.driver', 'sentinel');
$this->provider->register();
$this->provider->boot();

Expand Down Expand Up @@ -112,6 +102,10 @@ public function testBootExtendsSessionHandlers()
$this->provider->register();
$this->provider->boot();

$this->assertNotNull($this->app->session->driver('redis-sentinel'));
if (ApplicationFactory::isLumen()) {
$this->assertFalse($this->app->bound('session'));
} else {
$this->assertNotNull($this->app->session->driver('redis-sentinel'));
}
}
}
101 changes: 101 additions & 0 deletions tests/Support/ApplicationFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace Monospice\LaravelRedisSentinel\Tests\Support;

use Illuminate\Cache\CacheServiceProvider;
use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Queue\QueueServiceProvider;
use Illuminate\Redis\RedisServiceProvider;
use Illuminate\Session\SessionServiceProvider;

class ApplicationFactory
{
/**
* Bootstrap a Laravel or Lumen application to run tests against.
*
* @param bool $configure If TRUE, configure default application components
* for tests
*
* @return \Illuminate\Contracts\Container\Container The appropriate
* application instance for the framework under test
*/
public static function make($configure = true)
{
if (static::isLumen()) {
return static::makeLumenApplication($configure);
}

return static::makeLaravelApplication($configure);
}

/**
* Get the version of the Laravel framework used by the package under test.
*
* @return string The version string of the framework
*/
public static function getApplicationVersion()
{
if (static::isLumen()) {
return substr(static::makeLumenApplication()->version(), 7, 3);
}

return \Illuminate\Foundation\Application::VERSION;
}

/**
* Bootstrap a Laravel application instance to run tests against.
*
* @param bool $configure If TRUE, configure default application components
* for tests
*
* @return \Illuminate\Foundation\Application The Laravel application
* instance
*/
public static function makeLaravelApplication($configure = true)
{
$app = new \Illuminate\Foundation\Application();
$app->register(new CacheServiceProvider($app));
$app->register(new QueueServiceProvider($app));
$app->register(new SessionServiceProvider($app));
$app->register(new RedisServiceProvider($app));

$app->config = new ConfigRepository();

return $app;
}

/**
* Bootstrap a Lumen application instance to run tests against.
*
* @param bool $configure If TRUE, configure default application components
* for tests
*
* @return \Laravel\Lumen\Application The Lumen application instance
*/
public static function makeLumenApplication($configure = true)
{
// Set the base path so the application doesn't attempt to use the
// package's config directory as the application config directory
// during tests:
$app = new \Laravel\Lumen\Application(__DIR__ . '/..');

if ($configure) {
$app->register(RedisServiceProvider::class);
$app->configure('database');
$app->configure('cache');
$app->configure('queue');
}

return $app;
}

/**
* Determine if the test is running against a Laravel or Lumen framework.
*
* @return bool True if running the test against Lumen
*/
public static function isLumen()
{
return class_exists('Laravel\Lumen\Application');
}
}
Loading

0 comments on commit 70dbe1d

Please sign in to comment.