From 04fe81965aa1a1c9a3f780213a42155ac2e6a507 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Tue, 23 Sep 2014 17:00:37 +0200 Subject: [PATCH 01/12] Initial version of RedisSource --- Model/Datasource/RedisSource.php | 174 ++++++++++++++++++ Model/Datasource/empty | 0 .../Case/Model/Datasource/RedisSourceTest.php | 28 +++ Test/Case/Model/Datasource/empty | 0 4 files changed, 202 insertions(+) create mode 100644 Model/Datasource/RedisSource.php delete mode 100644 Model/Datasource/empty create mode 100644 Test/Case/Model/Datasource/RedisSourceTest.php delete mode 100644 Test/Case/Model/Datasource/empty diff --git a/Model/Datasource/RedisSource.php b/Model/Datasource/RedisSource.php new file mode 100644 index 0000000..2a925a2 --- /dev/null +++ b/Model/Datasource/RedisSource.php @@ -0,0 +1,174 @@ + '127.0.0.1', + 'port' => 6379, + 'password' => '', + 'database' => 0, + 'timeout' => 0, + 'persistent' => true, + 'unix_socket' => '', + 'prefix' => '', + ); + +/** + * Configuration. + * + * @var array + */ + public $config = array(); + +/** + * A reference to the physical connection of this DataSource. + * + * @var Redis + */ + protected $_connection = null; + +/** + * Constructor. + * + * Opens the connection to the server (if needed). + * + * @param array $config Array of configuration information for the Datasource + * @param bool $autoConnect Whether or not the datasource should automatically connect + * @return bool If autoconnect is true, true if the database could be connected, else false, otherwise, (always) true + * @throws MissingConnectionException when a connection cannot be made + */ + public function __construct($config = null, $autoConnect = true) { + parent::__construct($config); + + if (!$this->enabled()) { + throw new MissingConnectionException(array( + 'class' => get_class($this), + 'message' => __d('cake_dev', 'Selected driver is not enabled'), + 'enabled' => false + )); + } + + if ($autoConnect) { + return $this->connect(); + } + + return true; + } + +/** + * Destructor. + * + * Closes the connection to the server (if needed). + * + * @return void + */ + public function __destruct() { + if (!$this->config['persistent']) { + $this->close(); + } + } + +/** + * Check that the redis extension is installed/loaded. + * + * @return bool Whether or not the extension is loaded + */ + public function enabled() { + return extension_loaded('redis'); + } + +/** + * Connects to the database using options in the given configuration array. + * + * @return bool True if the database could be connected, else false + * @throws MissingConnectionException + */ + public function connect() { + $this->connected = false; + + try { + $this->_connection = new Redis(); + $this->connected = true; + + } catch (Exception $e) { + throw new MissingConnectionException(array('class' => get_class($this), 'message' => $e->getMessage())); + } + + return $this->connected; + } + +/** + * Closes a connection. + * + * @return bool Always true + */ + public function close() { + if ($this->isConnected()) { + $this->_connection->close(); + unset($this->_connection); + } + + $this->connected = false; + + return true; + } + +/** + * Checks if the source is connected to the database. + * + * @return bool True if the database is connected, else false + */ + public function isConnected() { + return $this->connected; + } + +/** + * Caches/returns cached results for child instances. + * + * @param mixed $data List of tables + * @return array Array of sources available in this datasource + */ + public function listSources($data = null) { + return null; + } + +/** + * Returns a Model description (metadata) or null if none found. + * + * @param Model|string $model Name of database table to inspect or model instance + * @return array Array of Metadata for the $model + */ + public function describe($model) { + return null; + } + +/** + * Returns an SQL calculation, i.e. COUNT() or MAX() + * + * @param Model $Model The model to get a calculated field for + * @param string $func Lowercase name of SQL function, i.e. 'count' or 'max' + * @param array $params Function parameters (any values must be quoted manually) + * @return string An SQL calculation function + */ + public function calculate(Model $Model, $func, $params = array()) { + return array('count' => true); + } + +} diff --git a/Model/Datasource/empty b/Model/Datasource/empty deleted file mode 100644 index e69de29..0000000 diff --git a/Test/Case/Model/Datasource/RedisSourceTest.php b/Test/Case/Model/Datasource/RedisSourceTest.php new file mode 100644 index 0000000..abf71b5 --- /dev/null +++ b/Test/Case/Model/Datasource/RedisSourceTest.php @@ -0,0 +1,28 @@ + Date: Fri, 24 Oct 2014 11:21:33 +0200 Subject: [PATCH 02/12] Added functionality and did some cleanup --- Model/Datasource/RedisSource.php | 132 ++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 30 deletions(-) diff --git a/Model/Datasource/RedisSource.php b/Model/Datasource/RedisSource.php index 2a925a2..9467846 100644 --- a/Model/Datasource/RedisSource.php +++ b/Model/Datasource/RedisSource.php @@ -20,12 +20,12 @@ class RedisSource extends DataSource { * @var array */ protected $_baseConfig = array( - 'server' => '127.0.0.1', + 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'database' => 0, 'timeout' => 0, - 'persistent' => true, + 'persistent' => false, 'unix_socket' => '', 'prefix' => '', ); @@ -45,37 +45,32 @@ class RedisSource extends DataSource { protected $_connection = null; /** - * Constructor. + * Whether or not we are connected to the DataSource. * - * Opens the connection to the server (if needed). - * - * @param array $config Array of configuration information for the Datasource - * @param bool $autoConnect Whether or not the datasource should automatically connect - * @return bool If autoconnect is true, true if the database could be connected, else false, otherwise, (always) true - * @throws MissingConnectionException when a connection cannot be made + * @var bool */ - public function __construct($config = null, $autoConnect = true) { + public $connected = false; + +/** + * Constructor. + * + * @param array $config Array of configuration information for the Datasource + * @return bool True if connecting to the DataSource succeeds, else false + */ + public function __construct($config = array()) { parent::__construct($config); if (!$this->enabled()) { - throw new MissingConnectionException(array( - 'class' => get_class($this), - 'message' => __d('cake_dev', 'Selected driver is not enabled'), - 'enabled' => false - )); + return false; } - if ($autoConnect) { - return $this->connect(); - } - - return true; + return $this->connect(); } /** * Destructor. * - * Closes the connection to the server (if needed). + * Closes the connection to the host (if needed). * * @return void */ @@ -86,7 +81,18 @@ public function __destruct() { } /** - * Check that the redis extension is installed/loaded. + * Passes (non-existing) method calls to `Redis`. + * + * @param string $name The name of the method being called + * @param array $arguments An enumerated array containing the parameters passed to the method + * @return mixed Method return value + */ + public function __call($name, $arguments) { + return call_user_func_array(array($this->_connection, $name), $arguments); + } + +/** + * Check that the redis extension is loaded. * * @return bool Whether or not the extension is loaded */ @@ -97,21 +103,87 @@ public function enabled() { /** * Connects to the database using options in the given configuration array. * - * @return bool True if the database could be connected, else false - * @throws MissingConnectionException + * "Connects mean: + * - connect + * - authenticate + * - select + * - setPrefix + * + * @return bool */ public function connect() { - $this->connected = false; + $this->connected = $this->_connect(); + $this->connected = $this->connected && $this->_authenticate(); + $this->connected = $this->connected && $this->_select(); + $this->connected = $this->connected && !$this->_setPrefix(); + + return $this->connected; + } +/** + * Connects to the database using options in the given configuration array. + * + * @return bool True if connecting to the DataSource succeeds, else false + */ + protected function _connect() { try { $this->_connection = new Redis(); - $this->connected = true; - } catch (Exception $e) { - throw new MissingConnectionException(array('class' => get_class($this), 'message' => $e->getMessage())); + if ($this->config['unix_socket']) { + return $this->_connection->connect($this->config['unix_socket']); + } elseif (!$this->config['persistent']) { + return $this->_connection->connect( + $this->config['host'], $this->config['port'], $this->config['timeout'] + ); + } else { + $persistentId = crc32(serialize($this->config)); + + return $this->_connection->pconnect( + $this->config['host'], $this->config['port'], $this->config['timeout'], $persistentId + ); + } + } catch (RedisException $e) { + return false; } + } - return $this->connected; +/** + * Authenticates to the database (if needed) using options in the given configuration array. + * + * @return bool True if the authentication succeeded or no password was specified, else false + */ + protected function _authenticate() { + if ($this->config['password']) { + return $this->_connection->auth($this->config['password']); + } + + return true; + } + +/** + * Selects a database (if needed) using options in the given configuration array. + * + * @return bool True if the select succeeded or no database was specified, else false + */ + protected function _select() { + if ($this->config['database']) { + return $this->_connection->select($this->config['database']); + } + + return true; + } + +/** + * Sets a prefix for all keys (if needed) using options in the given configuration array. + * + * @return bool True if setting the prefix succeeded or no prefix was specified, else false + */ + protected function _setPrefix() { + if ($this->config['prefix']) { + return $this->_connection->setOption(Redis::OPT_PREFIX, $this->config['prefix']); + } + + return true; } /** @@ -122,10 +194,10 @@ public function connect() { public function close() { if ($this->isConnected()) { $this->_connection->close(); - unset($this->_connection); } $this->connected = false; + $this->_connection = null; return true; } From 89cc404bfcc048529104c89b4dcd6d16b93ba625 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 11:56:25 +0200 Subject: [PATCH 03/12] Added some simple tests --- .../Case/Model/Datasource/RedisSourceTest.php | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/Test/Case/Model/Datasource/RedisSourceTest.php b/Test/Case/Model/Datasource/RedisSourceTest.php index abf71b5..35dae76 100644 --- a/Test/Case/Model/Datasource/RedisSourceTest.php +++ b/Test/Case/Model/Datasource/RedisSourceTest.php @@ -1,8 +1,8 @@ listSources(); + + $this->assertNull($result); + } + +/** + * testListSources method + * + * @return void + */ + public function testDescribe() { + $Source = new RedisSource(); + $Model = $this->getMockForModel('Model'); + + $result = $Source->describe($Model); + + $this->assertNull($result); + } + +/** + * testListSources method + * + * @return void + */ + public function testCalculate() { + $Source = new RedisSource(); + $Model = $this->getMockForModel('Model'); + $func = 'foo'; + $params = array('b', 'a', 'r'); + + $result = $Source->calculate($Model, $func, $params); + $expected = array('count' => true); + + $this->assertIdentical($expected, $result); + } + } From 486dc6f3d9e666c27fd6c2872a883c001ea72e77 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 16:30:08 +0200 Subject: [PATCH 04/12] Added tests And some TODOS --- .travis.yml | 9 +- Model/Datasource/RedisSource.php | 28 +- .../Case/Model/Datasource/RedisSourceTest.php | 552 +++++++++++++++++- 3 files changed, 575 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 964a4d5..196a027 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,18 +4,19 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 env: global: - REPO_NAME=cakephp-redis - PLUGIN_NAME=Redis - REQUIRE="" - - DB=mysql CAKE_VERSION=master + - DB=redis CAKE_VERSION=master matrix: - - DB=mysql CAKE_VERSION=2.3 - - DB=mysql CAKE_VERSION=2.4 - - DB=mysql CAKE_VERSION=2.5 + - DB=redis CAKE_VERSION=2.3 + - DB=redis CAKE_VERSION=2.4 + - DB=redis CAKE_VERSION=2.5 matrix: include: diff --git a/Model/Datasource/RedisSource.php b/Model/Datasource/RedisSource.php index 9467846..907c9f4 100644 --- a/Model/Datasource/RedisSource.php +++ b/Model/Datasource/RedisSource.php @@ -51,6 +51,13 @@ class RedisSource extends DataSource { */ public $connected = false; +/** + * Whether or not source data like available tables and schema descriptions should be cached. + * + * @var bool + */ + public $cacheSources = false; + /** * Constructor. * @@ -64,6 +71,8 @@ public function __construct($config = array()) { return false; } + $this->_connection = new Redis(); + return $this->connect(); } @@ -73,6 +82,7 @@ public function __construct($config = array()) { * Closes the connection to the host (if needed). * * @return void + * @todo Write test */ public function __destruct() { if (!$this->config['persistent']) { @@ -86,8 +96,13 @@ public function __destruct() { * @param string $name The name of the method being called * @param array $arguments An enumerated array containing the parameters passed to the method * @return mixed Method return value + * @todo Throw exception(s) */ public function __call($name, $arguments) { + if (!method_exists($this->_connection, $name)) { + return false; + } + return call_user_func_array(array($this->_connection, $name), $arguments); } @@ -115,7 +130,7 @@ public function connect() { $this->connected = $this->_connect(); $this->connected = $this->connected && $this->_authenticate(); $this->connected = $this->connected && $this->_select(); - $this->connected = $this->connected && !$this->_setPrefix(); + $this->connected = $this->connected && $this->_setPrefix(); return $this->connected; } @@ -126,9 +141,8 @@ public function connect() { * @return bool True if connecting to the DataSource succeeds, else false */ protected function _connect() { + // TODO: Remove useless try / catch? try { - $this->_connection = new Redis(); - if ($this->config['unix_socket']) { return $this->_connection->connect($this->config['unix_socket']); } elseif (!$this->config['persistent']) { @@ -192,6 +206,7 @@ protected function _setPrefix() { * @return bool Always true */ public function close() { + // TODO: Remove useless condition if ($this->isConnected()) { $this->_connection->close(); } @@ -216,9 +231,10 @@ public function isConnected() { * * @param mixed $data List of tables * @return array Array of sources available in this datasource + * @todo: Remove useless method? */ public function listSources($data = null) { - return null; + return parent::listSources($data); } /** @@ -226,9 +242,10 @@ public function listSources($data = null) { * * @param Model|string $model Name of database table to inspect or model instance * @return array Array of Metadata for the $model + * @todo: Remove useless method? */ public function describe($model) { - return null; + return parent::describe($model); } /** @@ -238,6 +255,7 @@ public function describe($model) { * @param string $func Lowercase name of SQL function, i.e. 'count' or 'max' * @param array $params Function parameters (any values must be quoted manually) * @return string An SQL calculation function + * @todo Remove useless method? */ public function calculate(Model $Model, $func, $params = array()) { return array('count' => true); diff --git a/Test/Case/Model/Datasource/RedisSourceTest.php b/Test/Case/Model/Datasource/RedisSourceTest.php index 35dae76..991480c 100644 --- a/Test/Case/Model/Datasource/RedisSourceTest.php +++ b/Test/Case/Model/Datasource/RedisSourceTest.php @@ -1,6 +1,67 @@ getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + // Set expectations for constructor calls + $Source->expects($this->once())->method('enabled')->will($this->returnValue(false)); + $Source->expects($this->never())->method('connect'); + + // Now call the constructor + $reflectedClass = new ReflectionClass('TestRedisSource'); + $constructor = $reflectedClass->getConstructor(); + $constructor->invoke($Source); + } + +/** + * testConstructExtensionLoaded method + * + * Tests that `connect` will be called when redis extension is loaded. + * + * @return void + */ + public function testConstructExtensionLoaded() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + // Set expectations for constructor calls + $Source->expects($this->once())->method('enabled')->will($this->returnValue(true)); + $Source->expects($this->once())->method('connect'); + + // Now call the constructor + $reflectedClass = new ReflectionClass('TestRedisSource'); + $constructor = $reflectedClass->getConstructor(); + $constructor->invoke($Source); + + $expected = 'Redis'; + $result = $Source->_connection; + + $this->assertInstanceOf($expected, $result); + } + +/** + * testConnected method + * + * @return void + */ + public function testIsConnected() { + $Source = new TestRedisSource(); + + $Source->connected = true; + $result = $Source->isConnected(); + + $this->assertTrue($result); + + $Source->connected = false; + $result = $Source->isConnected(); + + $this->assertFalse($result); + } + +/** + * testConnectException method + * + * @return void + */ + public function testConnectException() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $unixSocket = '/foo/bar'; + + $Source->config = array('unix_socket' => $unixSocket); + $Source->_connection = $this->getMock('Redis', array('connect')); + + // Set expectations for connect calls + $Source->_connection->expects($this->once())->method('connect') + ->with($this->equalTo($unixSocket))->will($this->throwException(new RedisException)); + + // Now call _connect + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_connect'); + $result = $connect->invoke($Source); + + $this->assertFalse($result); + } + +/** + * testConnectUnixSocket method + * + * @return void + */ + public function testConnectUnixSocket() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $unixSocket = '/foo/bar'; + + $Source->config = array('unix_socket' => $unixSocket); + $Source->_connection = $this->getMock('Redis', array('connect')); + + // Set expectations for connect calls + $Source->_connection->expects($this->once())->method('connect') + ->with($this->equalTo($unixSocket))->will($this->returnValue(true)); + + // Now call _connect + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_connect'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testConnectTcp method + * + * @return void + */ + public function testConnectTcp() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $unixSocket = ''; + $persistent = false; + $host = 'foo'; + $port = 'bar'; + $timeout = 0; + + $Source->config = array( + 'unix_socket' => $unixSocket, + 'persistent' => $persistent, + 'host' => $host, + 'port' => $port, + 'timeout' => $timeout, + ); + $Source->_connection = $this->getMock('Redis', array('connect')); + + // Set expectations for connect calls + $Source->_connection->expects($this->once())->method('connect') + ->with($this->equalTo($host), $this->equalTo($port), $this->equalTo($timeout)) + ->will($this->returnValue(true)); + + // Now call _connect + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_connect'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testConnectTcpPersistent method + * + * @return void + */ + public function testConnectTcpPersistent() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $unixSocket = ''; + $persistent = true; + $host = 'foo'; + $port = 'bar'; + $timeout = 0; + + $Source->config = array( + 'unix_socket' => $unixSocket, + 'persistent' => $persistent, + 'host' => $host, + 'port' => $port, + 'timeout' => $timeout, + ); + $Source->_connection = $this->getMock('Redis', array('pconnect')); + + // Set expectations for pconnect calls + $Source->_connection->expects($this->once())->method('pconnect') + ->with($this->equalTo($host), $this->equalTo($port), $this->equalTo($timeout), $this->anything()) + ->will($this->returnValue(true)); + + // Now call _connect + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_connect'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testCall method + * + * @return void + */ + public function testCall() { + $Source = new TestRedisSource(); + + // + // Existing method + // + + $result = $Source->ping(); + $expected = '+PONG'; + + $this->assertIdentical($result, $expected); + + // + // Non-existing method + // + + $result = $Source->pang(); + + $this->assertFalse($result); + } + +/** + * testNoAuthenticate method + * + * @return void + */ + public function testNoAuthenticate() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $password = ''; + + $Source->config = array('password' => $password); + $Source->_connection = $this->getMock('Redis', array('auth')); + + // Set expectations for constructor calls + $Source->_connection->expects($this->never())->method('auth'); + + // Now call _authenticate + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_authenticate'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testSuccessfulAuthenticate method + * + * @return void + */ + public function testSuccessfulAuthenticate() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $password = 'foo'; + + $Source->config = array('password' => $password); + $Source->_connection = $this->getMock('Redis', array('auth')); + + // Set expectations for auth calls + $Source->_connection->expects($this->once())->method('auth') + ->with($this->equalTo($password))->will($this->returnValue(true)); + + // Now call _authenticate + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_authenticate'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testFailingAuthenticate method + * + * @return void + */ + public function testFailingAuthenticate() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $password = 'foo'; + + $Source->config = array('password' => $password); + $Source->_connection = $this->getMock('Redis', array('auth')); + + // Set expectations for auth calls + $Source->_connection->expects($this->once())->method('auth') + ->with($this->equalTo($password))->will($this->returnValue(false)); + + // Now call _authenticate + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_authenticate'); + $result = $connect->invoke($Source); + + $this->assertFalse($result); + } + +/** + * testNoSelect method + * + * @return void + */ + public function testNoSelect() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $database = ''; + + $Source->config = array('database' => $database); + $Source->_connection = $this->getMock('Redis', array('select')); + + // Set expectations for select calls + $Source->_connection->expects($this->never())->method('select'); + + // Now call _Select + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_select'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testSuccessfulSelect method + * + * @return void + */ + public function testSuccessfulSelect() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $database = 'foo'; + + $Source->config = array('database' => $database); + $Source->_connection = $this->getMock('Redis', array('select')); + + // Set expectations for select calls + $Source->_connection->expects($this->once())->method('select') + ->with($this->equalTo($database))->will($this->returnValue(true)); + + // Now call _Select + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_select'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testFailingSelect method + * + * @return void + */ + public function testFailingSelect() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $database = 'foo'; + + $Source->config = array('database' => $database); + $Source->_connection = $this->getMock('Redis', array('select')); + + // Set expectations for select calls + $Source->_connection->expects($this->once())->method('select') + ->with($this->equalTo($database))->will($this->returnValue(false)); + + // Now call _Select + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_select'); + $result = $connect->invoke($Source); + + $this->assertFalse($result); + } + +/** + * testNoSelect method + * + * @return void + */ + public function testNoSetPrefix() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $prefix = ''; + + $Source->config = array('prefix' => $prefix); + $Source->_connection = $this->getMock('Redis', array('setOption')); + + // Set expectations for setOption calls + $Source->_connection->expects($this->never())->method('setOption'); + + // Now call _Select + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_setPrefix'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testSuccessfulSelect method + * + * @return void + */ + public function testSuccessfulSetPrefix() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $prefix = 'foo'; + + $Source->config = array('prefix' => $prefix); + $Source->_connection = $this->getMock('Redis', array('setOption')); + + // Set expectations for setOption calls + $Source->_connection->expects($this->once())->method('setOption') + ->with($this->equalTo(Redis::OPT_PREFIX), $this->equalTo($prefix))->will($this->returnValue(true)); + + // Now call _Select + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_setPrefix'); + $result = $connect->invoke($Source); + + $this->assertTrue($result); + } + +/** + * testFailingSelect method + * + * @return void + */ + public function testFailingSetPrefix() { + // Get mock, without the constructor being called + $Source = $this->getMockBuilder('TestRedisSource')->disableOriginalConstructor()->getMock(); + + $prefix = 'foo'; + + $Source->config = array('prefix' => $prefix); + $Source->_connection = $this->getMock('Redis', array('setOption')); + + // Set expectations for setOption calls + $Source->_connection->expects($this->once())->method('setOption') + ->with($this->equalTo(Redis::OPT_PREFIX), $this->equalTo($prefix))->will($this->returnValue(false)); + + // Now call _Select + $reflectedClass = new ReflectionClass('TestRedisSource'); + $connect = $reflectedClass->getMethod('_setPrefix'); + $result = $connect->invoke($Source); + + $this->assertFalse($result); + } + + public function testCloseNotConnected() { + $Source = new TestRedisSource(); + + $Source->connected = false; + $Source->_connection = $this->getMock('Redis', array('close')); + + // Set expectations for close calls + $Source->_connection->expects($this->never())->method('close'); + + $result = $Source->close(); + + $this->assertFalse($Source->connected); + $this->assertNull($Source->_connection); + $this->assertTrue($result); + } + + public function testCloseConnected() { + $Source = new TestRedisSource(); + + $Source->connected = true; + $Source->_connection = $this->getMock('Redis', array('close')); + + // Set expectations for close calls + $Source->_connection->expects($this->once())->method('close'); + + $result = $Source->close(); + + $this->assertFalse($Source->connected); + $this->assertNull($Source->_connection); + $this->assertTrue($result); + } + /** * testListSources method * * @return void */ public function testListSources() { - $Source = new RedisSource(); + $Source = new TestRedisSource(); $result = $Source->listSources(); @@ -39,12 +581,12 @@ public function testListSources() { } /** - * testListSources method + * testDescribe method * * @return void */ public function testDescribe() { - $Source = new RedisSource(); + $Source = new TestRedisSource(); $Model = $this->getMockForModel('Model'); $result = $Source->describe($Model); @@ -53,12 +595,12 @@ public function testDescribe() { } /** - * testListSources method + * testCalculate method * * @return void */ public function testCalculate() { - $Source = new RedisSource(); + $Source = new TestRedisSource(); $Model = $this->getMockForModel('Model'); $func = 'foo'; $params = array('b', 'a', 'r'); From bafa6153088464e38527c078442b1a3bd2c44130 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 16:32:20 +0200 Subject: [PATCH 05/12] Added packagist badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a41356b..765a4fe 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Redis (DataSource) plugin for CakePHP -[![Build Status](https://travis-ci.org/Oefenweb/cakephp-redis.png?branch=master)](https://travis-ci.org/Oefenweb/cakephp-redis) [![Coverage Status](https://coveralls.io/repos/Oefenweb/cakephp-redis/badge.png)](https://coveralls.io/r/Oefenweb/cakephp-redis) +[![Build Status](https://travis-ci.org/Oefenweb/cakephp-redis.png?branch=master)](https://travis-ci.org/Oefenweb/cakephp-redis) [![Coverage Status](https://coveralls.io/repos/Oefenweb/cakephp-redis/badge.png)](https://coveralls.io/r/Oefenweb/cakephp-redis) [![Packagist downloads](http://img.shields.io/packagist/dt/Oefenweb/cakephp-redis.svg)](https://packagist.org/packages/oefenweb/cakephp-redis) The Redis (DataSource) plugin ... From fe2cc6c9ada32294e6846d23ff622a9965e8cffe Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 16:50:40 +0200 Subject: [PATCH 06/12] Fix for failing build --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 196a027..b598a08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,8 @@ matrix: before_script: - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis - ../travis/before_script.sh + - pwd && ls + - wget https://github.com/nicolasff/phpredis/archive/2.2.5.zip -O php-redis.zip && unzip php-redis.zip && cd phpredis-2.2.5/ && mkdeb.sh && dpkg -i phpredis-2.2.5_*.deb script: - ../travis/script.sh From 36d7f1be1fd18068b30a6cc3d58e0f3f04826061 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 16:54:12 +0200 Subject: [PATCH 07/12] Fix for failing build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b598a08..3c669c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ before_script: - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis - ../travis/before_script.sh - pwd && ls - - wget https://github.com/nicolasff/phpredis/archive/2.2.5.zip -O php-redis.zip && unzip php-redis.zip && cd phpredis-2.2.5/ && mkdeb.sh && dpkg -i phpredis-2.2.5_*.deb + - wget https://github.com/nicolasff/phpredis/archive/2.2.5.zip -O php-redis.zip && unzip php-redis.zip && cd phpredis-2.2.5/ && ./mkdeb.sh && dpkg -i phpredis-2.2.5_*.deb script: - ../travis/script.sh From 46c851dbcb1e6df59c42ecc3ae2be9c99c810dbe Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 17:06:22 +0200 Subject: [PATCH 08/12] Fix for failing build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3c669c5..99ada52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ before_script: - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis - ../travis/before_script.sh - pwd && ls - - wget https://github.com/nicolasff/phpredis/archive/2.2.5.zip -O php-redis.zip && unzip php-redis.zip && cd phpredis-2.2.5/ && ./mkdeb.sh && dpkg -i phpredis-2.2.5_*.deb + - wget https://github.com/nicolasff/phpredis/archive/2.2.5.zip -O php-redis.zip && unzip php-redis.zip && cd phpredis-2.2.5/ && phpize && ./configure && make && make install && echo \"extension=redis.so\" >> `php --ini | grep \"Loaded Configuration\" | sed -e \"s|.*:\s*||\"` script: - ../travis/script.sh From 68f6fc09033c69a9c4deae84c8f94089da3b4384 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 17:15:06 +0200 Subject: [PATCH 09/12] Enable pre-installed redis extension on travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99ada52..0829c0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,8 +33,8 @@ matrix: before_script: - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis - ../travis/before_script.sh - - pwd && ls - - wget https://github.com/nicolasff/phpredis/archive/2.2.5.zip -O php-redis.zip && unzip php-redis.zip && cd phpredis-2.2.5/ && phpize && ./configure && make && make install && echo \"extension=redis.so\" >> `php --ini | grep \"Loaded Configuration\" | sed -e \"s|.*:\s*||\"` + - echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - phpenv rehash script: - ../travis/script.sh From fb362cbd1ce910c7e1e69ff72a3784408dab9614 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 20:16:23 +0200 Subject: [PATCH 10/12] Fixed indent --- Model/Datasource/RedisSource.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Model/Datasource/RedisSource.php b/Model/Datasource/RedisSource.php index 907c9f4..4af812b 100644 --- a/Model/Datasource/RedisSource.php +++ b/Model/Datasource/RedisSource.php @@ -59,11 +59,11 @@ class RedisSource extends DataSource { public $cacheSources = false; /** - * Constructor. - * - * @param array $config Array of configuration information for the Datasource - * @return bool True if connecting to the DataSource succeeds, else false - */ + * Constructor. + * + * @param array $config Array of configuration information for the Datasource + * @return bool True if connecting to the DataSource succeeds, else false + */ public function __construct($config = array()) { parent::__construct($config); From 5c76ce294cd71beea56cdfb534868f864c441102 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 20:19:28 +0200 Subject: [PATCH 11/12] Forgot the add redis-server service --- .travis.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0829c0e..e7b47ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,17 +6,20 @@ php: - 5.5 - 5.6 +services: + - redis-server + env: global: - REPO_NAME=cakephp-redis - PLUGIN_NAME=Redis - REQUIRE="" - - DB=redis CAKE_VERSION=master + - DB=mysql CAKE_VERSION=master matrix: - - DB=redis CAKE_VERSION=2.3 - - DB=redis CAKE_VERSION=2.4 - - DB=redis CAKE_VERSION=2.5 + - DB=mysql CAKE_VERSION=2.3 + - DB=mysql CAKE_VERSION=2.4 + - DB=mysql CAKE_VERSION=2.5 matrix: include: @@ -31,10 +34,10 @@ matrix: - FOC_VALIDATE=1 before_script: - - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis - - ../travis/before_script.sh - echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - phpenv rehash + - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis + - ../travis/before_script.sh script: - ../travis/script.sh From 690b8dfdeec11248778679b2ad46df7a3b5545e2 Mon Sep 17 00:00:00 2001 From: Mischa ter Smitten Date: Fri, 24 Oct 2014 20:21:56 +0200 Subject: [PATCH 12/12] Added hipchat notifications --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index e7b47ee..cb3980c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,3 +47,6 @@ after_success: notifications: email: false + hipchat: + rooms: + secure: BgtN4zIM+HqmIIvGb5aJz3vuu2ACF5k/1iJb32B/BSZE7hQxJ9iSsnY0naZzv81cmFVXmndzp4I4dM8wLrISScqSz3iM7NNVxMSm+FVQt63DckikO39Slyh8HfSyY3pxuIzPuecuIs85Li1z2KnBue34QRyMqmaAYS+sdTXZONM=