mirror of
https://github.com/predis/predis.git
synced 2026-08-24 12:09:32 +00:00
388 lines
12 KiB
PHP
388 lines
12 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Predis package.
|
|
*
|
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Predis\Network;
|
|
|
|
use \PHPUnit_Framework_TestCase as StandardTestCase;
|
|
|
|
use Predis\ConnectionParameters;
|
|
use Predis\Profiles\ServerProfile;
|
|
|
|
/**
|
|
* @group realm-connection
|
|
*/
|
|
abstract class ConnectionTestCase extends StandardTestCase
|
|
{
|
|
/**
|
|
* @group disconnected
|
|
* @group slow
|
|
* @expectedException Predis\Network\ConnectionException
|
|
*/
|
|
public function testThrowExceptionWhenUnableToConnect()
|
|
{
|
|
$parameters = array('host' => '169.254.10.10', 'connection_timeout' => 0.5);
|
|
$connection = $this->getConnection($profile, false, $parameters);
|
|
$connection->executeCommand($this->getProfile()->createCommand('ping'));
|
|
}
|
|
|
|
// ******************************************************************** //
|
|
// ---- INTEGRATION TESTS --------------------------------------------- //
|
|
// ******************************************************************** //
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testConnectForcesConnection()
|
|
{
|
|
$connection = $this->getConnection();
|
|
|
|
$this->assertFalse($connection->isConnected());
|
|
$connection->connect();
|
|
$this->assertTrue($connection->isConnected());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
* @expectedException Predis\ClientException
|
|
* @expectedExceptionMessage Connection already estabilished
|
|
*/
|
|
public function testThrowsExceptionOnConnectWhenAlreadyConnected()
|
|
{
|
|
$connection = $this->getConnection();
|
|
|
|
$connection->connect();
|
|
$connection->connect();
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testDisconnectForcesDisconnection()
|
|
{
|
|
$connection = $this->getConnection();
|
|
|
|
$connection->connect();
|
|
$this->assertTrue($connection->isConnected());
|
|
|
|
$connection->disconnect();
|
|
$this->assertFalse($connection->isConnected());
|
|
}
|
|
|
|
/**
|
|
* @group disconnected
|
|
*/
|
|
public function testDoesNotThrowExceptionOnDisconnectWhenAlreadyDisconnected()
|
|
{
|
|
$connection = $this->getConnection();
|
|
|
|
$this->assertFalse($connection->isConnected());
|
|
$connection->disconnect();
|
|
$this->assertFalse($connection->isConnected());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testGetResourceForcesConnection()
|
|
{
|
|
$connection = $this->getConnection();
|
|
|
|
$this->assertFalse($connection->isConnected());
|
|
$this->assertInternalType('resource', $connection->getResource());
|
|
$this->assertTrue($connection->isConnected());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testSendingCommandForcesConnection()
|
|
{
|
|
$connection = $this->getConnection($profile);
|
|
$cmdPing = $profile->createCommand('ping');
|
|
|
|
$this->assertTrue($connection->executeCommand($cmdPing));
|
|
$this->assertTrue($connection->isConnected());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testExecutesCommandOnServer()
|
|
{
|
|
$connection = $this->getConnection($profile);
|
|
|
|
$cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
|
|
$cmdPing->expects($this->once())
|
|
->method('parseResponse')
|
|
->with('PONG')
|
|
->will($this->returnValue(true));
|
|
|
|
$this->assertTrue($connection->executeCommand($cmdPing));
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testWritesCommandToServer()
|
|
{
|
|
$connection = $this->getConnection($profile);
|
|
|
|
$cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
|
|
$cmdPing->expects($this->never())
|
|
->method('parseResponse');
|
|
|
|
$connection->writeCommand($cmdPing);
|
|
$connection->disconnect();
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testReadsCommandFromServer()
|
|
{
|
|
$connection = $this->getConnection($profile);
|
|
|
|
$cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
|
|
$cmdPing->expects($this->once())
|
|
->method('parseResponse')
|
|
->with('PONG')
|
|
->will($this->returnValue(true));
|
|
|
|
$connection->writeCommand($cmdPing);
|
|
$this->assertTrue($connection->readResponse($cmdPing));
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testIsAbleToWriteMultipleCommandsAndReadThemBackForPipelining()
|
|
{
|
|
$connection = $this->getConnection($profile);
|
|
|
|
$cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
|
|
$cmdPing->expects($this->once())
|
|
->method('parseResponse')
|
|
->with('PONG')
|
|
->will($this->returnValue(true));
|
|
|
|
$cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
|
|
$cmdEcho->setArguments(array('ECHOED'));
|
|
$cmdEcho->expects($this->once())
|
|
->method('parseResponse')
|
|
->with('ECHOED')
|
|
->will($this->returnValue('ECHOED'));
|
|
|
|
$connection = $this->getConnection();
|
|
|
|
$connection->writeCommand($cmdPing);
|
|
$connection->writeCommand($cmdEcho);
|
|
|
|
$this->assertTrue($connection->readResponse($cmdPing));
|
|
$this->assertSame('ECHOED', $connection->readResponse($cmdEcho));
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testSendsInitializationCommandsOnConnection()
|
|
{
|
|
$connection = $this->getConnection($profile, true);
|
|
|
|
$cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
|
|
$cmdPing->expects($this->once())
|
|
->method('parseResponse')
|
|
->with('PONG')
|
|
->will($this->returnValue(true));
|
|
|
|
$cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
|
|
$cmdEcho->setArguments(array('ECHOED'));
|
|
$cmdEcho->expects($this->once())
|
|
->method('parseResponse')
|
|
->with('ECHOED')
|
|
->will($this->returnValue('ECHOED'));
|
|
|
|
$connection->pushInitCommand($cmdPing);
|
|
$connection->pushInitCommand($cmdEcho);
|
|
|
|
$connection->connect();
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testReadsStatusReplies()
|
|
{
|
|
$connection = $this->getConnection($profile, true);
|
|
|
|
$connection->writeCommand($profile->createCommand('set', array('foo', 'bar')));
|
|
$this->assertTrue($connection->read());
|
|
|
|
$connection->writeCommand($profile->createCommand('ping'));
|
|
$this->assertSame('PONG', $connection->read());
|
|
|
|
$connection->writeCommand($profile->createCommand('multi'));
|
|
$connection->writeCommand($profile->createCommand('ping'));
|
|
$this->assertTrue($connection->read());
|
|
$this->assertInstanceOf('Predis\ResponseQueued', $connection->read());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testReadsBulkReplies()
|
|
{
|
|
$connection = $this->getConnection($profile, true);
|
|
|
|
$connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
|
|
|
|
$connection->writeCommand($profile->createCommand('get', array('foo')));
|
|
$this->assertSame('bar', $connection->read());
|
|
|
|
$connection->writeCommand($profile->createCommand('get', array('hoge')));
|
|
$this->assertNull($connection->read());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testReadsIntegerReplies()
|
|
{
|
|
$connection = $this->getConnection($profile, true);
|
|
|
|
$connection->executeCommand($profile->createCommand('rpush', array('metavars', 'foo', 'hoge', 'lol')));
|
|
$connection->writeCommand($profile->createCommand('llen', array('metavars')));
|
|
|
|
$this->assertSame(3, $connection->read());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
* @expectedException Predis\ServerException
|
|
* @expectedExceptionMessage ERR Operation against a key holding the wrong kind of value
|
|
*/
|
|
public function testReadsErrorRepliesAsExceptions()
|
|
{
|
|
$connection = $this->getConnection($profile, true, array('throw_errors' => true));
|
|
|
|
$connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
|
|
$connection->writeCommand($profile->createCommand('rpush', array('foo', 'baz')));
|
|
|
|
$connection->read();
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testReadsErrorRepliesAsResponseErrorObjects()
|
|
{
|
|
$connection = $this->getConnection($profile, true, array('throw_errors' => false));
|
|
|
|
$connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
|
|
$connection->writeCommand($profile->createCommand('rpush', array('foo', 'baz')));
|
|
|
|
$this->assertInstanceOf('Predis\ResponseError', $error = $connection->read());
|
|
$this->assertSame('ERR Operation against a key holding the wrong kind of value', $error->getMessage());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
*/
|
|
public function testReadsMultibulkRepliesAsArrays()
|
|
{
|
|
$connection = $this->getConnection($profile, true);
|
|
|
|
$connection->executeCommand($profile->createCommand('rpush', array('metavars', 'foo', 'hoge', 'lol')));
|
|
$connection->writeCommand($profile->createCommand('lrange', array('metavars', 0, -1)));
|
|
|
|
$this->assertSame(array('foo', 'hoge', 'lol'), $connection->read());
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
* @group slow
|
|
* @expectedException Predis\Network\ConnectionException
|
|
* @expectedExceptionMessage Connection timed out
|
|
*/
|
|
public function testThrowsExceptionOnConnectionTimeout()
|
|
{
|
|
$connection = $this->getConnection($_, false, array('host' => '169.254.10.10', 'connection_timeout' => 0.5));
|
|
|
|
$connection->connect();
|
|
}
|
|
|
|
/**
|
|
* @group connected
|
|
* @group slow
|
|
* @expectedException Predis\Network\ConnectionException
|
|
*/
|
|
public function testThrowsExceptionOnReadWriteTimeout()
|
|
{
|
|
$connection = $this->getConnection($profile, true, array('read_write_timeout' => 0.5));
|
|
|
|
$connection->executeCommand($profile->createCommand('brpop', array('foo', 3)));
|
|
}
|
|
|
|
// ******************************************************************** //
|
|
// ---- HELPER METHODS ------------------------------------------------ //
|
|
// ******************************************************************** //
|
|
|
|
/**
|
|
* Returns a named array with the default connection parameters and their values.
|
|
*
|
|
* @return Array Default connection parameters.
|
|
*/
|
|
protected function getDefaultParametersArray()
|
|
{
|
|
return array(
|
|
'scheme' => 'tcp',
|
|
'host' => REDIS_SERVER_HOST,
|
|
'port' => REDIS_SERVER_PORT,
|
|
'database' => REDIS_SERVER_DBNUM,
|
|
'read_write_timeout' => 2,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns a new instance of connection parameters.
|
|
*
|
|
* @param array $additional Additional connection parameters.
|
|
* @return ConnectionParameters Default connection parameters.
|
|
*/
|
|
protected function getParameters($additional = array())
|
|
{
|
|
$parameters = array_merge($this->getDefaultParametersArray(), $additional);
|
|
$parameters = new ConnectionParameters($parameters);
|
|
|
|
return $parameters;
|
|
}
|
|
|
|
/**
|
|
* Returns a new instance of server profile.
|
|
*
|
|
* @param array $additional Additional connection parameters.
|
|
* @return ServerProfile
|
|
*/
|
|
protected function getProfile($version = null)
|
|
{
|
|
return ServerProfile::get($version ?: REDIS_SERVER_VERSION);
|
|
}
|
|
|
|
/**
|
|
* Returns a new instance of a connection instance.
|
|
*
|
|
* @param ServerProfile $profile Reference to the server profile instance.
|
|
* @param Boolean $initialize Push default initialization commands (SELECT and FLUSHDB).
|
|
* @param array $parameters Additional connection parameters.
|
|
* @return StreamConnection
|
|
*/
|
|
protected abstract function getConnection(&$profile = null, $initialize = false, Array $parameters = array());
|
|
}
|