Built out unit tests and most of functionality for Instance.

This commit is contained in:
Matt Butcher
2012-05-15 21:25:28 -05:00
parent 169528cad5
commit 097022706d
6 changed files with 365 additions and 4 deletions

View File

@@ -49,7 +49,7 @@ class DBaaS {
public static function newFromIdentity($identity) {
$endpoint = 'https://region-a.geo-1.dbaas-mysql.hpcloudsvc.com:443/v1.0/' . $identity->tenantId();
$endpoint = 'https://db-aw2az2-api0001.uswest.hpcloud.net:8779/v1.0/' . $identity->tenantId();
$dbaas = new DBaaS($identity->token(), $endpoint, $identity->tenantName());
return $dbaas;

View File

@@ -27,31 +27,107 @@ SOFTWARE.
namespace HPCloud\Services\DBaaS;
use \HPCloud\Transport;
class Instance {
protected $token;
protected $projectId;
protected $url;
protected $client;
public function __construct($token, $projectId, $endpoint) {
$this->token = $token;
$this->projectId = $projectId;
$this->url = $endpoint;
$this->client = Transport::instance();
}
public function describe($instanceId) {
$url = sprintf('%s/instances/%s', $this->url, $instanceId);
$res = $this->client->doRequest($url, 'GET', $this->headers());
$json = json_decode($res->content(), TRUE);
return InstanceDetails::newFromJSON($json);
}
public function listInstances() {
$url = $this->url . '/instances';
$res = $this->client->doRequest($url, 'GET', $this->headers());
$json = json_decode($res->content(), TRUE);
$list = array();
foreach ($json['instances'] as $instance) {
$list[] = InstanceDetails::newFromJSON($instance);
}
return $list;
}
/**
* Create a new database.
*
* This creates a database tuned according to the $flavor settings. The
* return data will include login/password and connection information.
*
* @attention
* This is the only time that the login and password info will be returned.
*
* @param string $name
* The name of the database.
* @param string $flavor
* The string flavor name. Known values are:
*- small
*- medium
* @param int $port
* If this is not specified, the default is used.
* @param array $typeSpec
* A typespec array.
* @retval object HPCloud::Services::DBaaS::InstanceDetails
* The details of creation, including login and password info.
* @see http://api-docs.hpcloud.com/hpcloud-dbaas/1.0/content/instance-create.html
*/
public function create($name, $flavor = 'medium', $port = NULL, $typeSpec = NULL) {
// Set type spec. As of the initial release of DBaaS, the only support
// type is mysql 5.5.
if (empty($typeSpec)) {
$typeSpec = array(
'name' => 'mysql',
'version' => '5.5',
);
}
$json = array(
'instance' => array(
'name' => $name,
'flavorRef' => $flavor,
'dbtype' => $typeSpec,
),
);
if (isset($port)) {
$json['instance']['port'] = $port;
}
$url = $this->url . '/instances';
$postData = json_encode($json);
$length = strlen($postData);
$headers = $this->headers(array('Accept' => 'application/json', 'Content-length' => $length));
$res = $this->client->doRequest($url, 'POST', $headers, $postData);
$results = json_decode($res->content(), TRUE);
return InstanceDetails::newFromJSON($results);
}
public function delete($instanceId) {
$url = sprintf('%s/instances/%s', $this->url, $instanceId);
$this->client->doRequest($url, 'DELETE', $this->headers());
return TRUE;
}
public function restart($instanceId) {
$url = sprintf('%s/instances/%s/restart', $this->url, $instanceId);
$headers = $this->headers(array('Content-Length' => '0'));
$this->client->doRequest($url, 'POST', $headers);
return TRUE;
}
/**
@@ -61,7 +137,18 @@ class Instance {
* The new (autogenerated) password.
*/
public function resetPassword($instanceId) {
$url = sprintf('%s/instances/%s/resetpassword', $this->url, $instanceId);
$headers = $this->headers(array('Content-Length' => '0'));
$res = $this->client->doRequest($url, 'POST', $headers);
$json = json_decode($res);
return $json->password;
}
protected function headers($add = array()) {
return $add + array(
'X-Auth-Token' => $this->token,
'X-Auth-Project-Id' => $this->projectId,
);
}
}

View File

@@ -28,4 +28,100 @@ SOFTWARE.
namespace HPCloud\Services\DBaaS;
class InstanceDetails {
protected $name;
protected $id;
protected $links;
protected $created;
protected $status;
protected $hostname;
protected $port;
protected $username;
protected $password;
public function newFromJSON($json) {
$o = new InstanceDetails($json['name'], $json['id']);
$o->links = $json['links'];
$o->created = $json['created'];
$o->status = $json['status'];
$o->hostname = $json['hostname'];
$o->port= !empty($json['port']) ? $json['port'] : '3306';
if (!empty($json['credential']['username'])) {
$o->username = $json['credential']['username'];
}
if (!empty($json['credential']['password'])) {
$o->username = $json['credential']['pasword'];
}
}
public function __construct($name, $id) {
}
public function createdOn() {
return $this->created;
}
public function status() {
return $this->status;
}
public function hostname() {
return $this->hostname;
}
public function port() {
return $this->port;
}
public function username() {
return $this->username;
}
public function password() {
return $this->password;
}
public function links() {
return $this->links;
}
/**
* Get the DSN to connect to the database instance.
*
* A convenience function for PDO.
*
* @see http://us3.php.net/manual/en/ref.pdo-mysql.connection.php
*
* @param string $dbName
* The name of the database to connect to. If none is specified,
* this will be left off of the DSN.
* @param string $charset
* This will attempt to set the character set. Not all versions
* of PHP use this.
*
* @retval string
* The DSN, including driver, host, port, and database name.
* @todo
* At this time, 'mysql' is hard-coded as the driver name. Does this
* need to change?
*/
public function dsn($dbName = NULL, $charset = NULL) {
$dsn = sprintf('mysql:host=%s;port=%s', $this->hostname(), $this->port());
if (!empty($dbName)) {
$dsn .= ';dbname=' . $dbName;
}
if (!empty($charset)) {
$dsn .= ';charset=' . $charset;
}
return $dsn;
}
}

View File

@@ -29,29 +29,201 @@ namespace HPCloud\Tests\Services\DBaaS;
require_once 'src/HPCloud/Bootstrap.php';
require_once 'test/TestCase.php';
use \HPCloud\Services\DBaaS;
use \HPCloud\Services\DBaaS\Instance;
/**
* @group dbaas
*/
class DBaaSInstanceTest extends \HPCloud\Tests\TestCase {
public function inst() {
$ident = $this->identity();
$dbaas = DBaaS::newFromIdentity($ident);
return $dbaas->instance();
}
public function destroyDatabase() {
$inst = $this->inst();
$list = $inst->listInstances();
fwrite(STDOUT, print_r($list, TRUE));
if (!empty($list['instances'])) {
$dbName = self::conf('hpcloud.dbaas.database');
foreach ($list['instances'] as $item) {
if ($item['name'] == $dbName) {
fprintf(STDOUT, "Deleting %s (%s)\n", $item['name'], $item['id']);
$inst->delete($item['id']);
}
}
}
}
public function testConstruct() {
$ident = $this->identity();
$dbaas = DBaaS::newFromIdentity($ident);
$endpoint = self::conf('hpcloud.dbaas.endpoint') . '/' . $ident->tenantId();
// Test #1: Build from scratch.
$inst = new Instance($ident->token(), $ident->tenantName(), $endpoint);
$this->assertInstanceOf('\HPCloud\Services\DBaaS\Instance', $inst);
// Test #2: Build from DBaaS.
$inst = $dbaas->instance();
$this->assertInstanceOf('\HPCloud\Services\DBaaS\Instance', $inst);
}
public function testCreate() {
// Make sure there aren't old fixtures hanging around from a
// failed run.
$this->destroyDatabase();
$dbName = self::conf('hpcloud.dbaas.database');
$details = $this->inst()->create($dbName, 'small', '3307');
$this->assertInstanceOf('\HPCloud\Services\DBaaS\InstanceDetails', $details);
$this->assertNotEmpty($details->username());
$this->assertNotEmpty($details->password());
$this->assertNotEmpty($details->id());
$this->assertNotEmpty($details->hostname());
$this->assertNotEmpty($details->port());
$this->assertNotEmpty($details->createdOn());
$this->assertEquals($dbName, $details->name());
$dsn = sprint('mysql:host=%s;port=3307;dbname=foo;charset=utf-8', $details->hostname());
$this->assertEquals($dsn, $details->dsn('foo', 'utf-8'));
$this->credentials = array(
'name' => $details->username(),
'pass' => $details->password(),
);
$this->dbId = $details->id();
$this->created = $details->createdOn();
}
/**
* @depends testCreate
*/
public function testDescribe() {
$dbName = self::conf('hpcloud.dbaas.database');
// Canary.
$this->assertNotEmpty($this->dbId);
$details = $this->inst()->describe($this->dbId);
$this->assertInstanceOf('\HPCloud\Services\DBaaS\InstanceDetails', $details);
$this->assertEmpty($details->username());
$this->assertEmpty($details->password());
$this->assertNotEmpty($details->hostname());
$this->assertNotEmpty($details->createdOn());
$this->assertEquals($this->dbId, $details->id());
$this->assertEquals($dbName, $details->name());
}
/**
* @depends testCreate
*/
public function testRestart() {
// Canary.
$this->assertNotEmpty($this->dbId);
$this->inst()->restart($this->dbId);
sleep(5);
$details = $this->inst()->details($this->dbId);
$this->assertEquals($this->created, $details->createdOn());
}
/**
* @depends testCreate
*/
public function testResetPassword() {
$pass = $this->credentials['pass'];
$this->assertNotEmpty($pass);
$newPass = $this->inst()->resetPassword($this->dbId);
$this->assertNotEmpty($newPass);
$this->assertNotEquals($pass, $newPass);
}
/**
* @depends testCreate
*/
public function testListInstances() {
$instances = $this->inst()->listInstances();
$this->assertNotEmpty($instances);
$this->assertGreaterThan(0, count($instances['instances']));
$match = 0;
$dbName = self::conf('hpcloud.dbaas.database');
foreach ($instances['instances'] as $server) {
$this->assertInstanceOf('\HPCloud\Services\DBaaS\InstanceDetails', $server);
$this->assertNotEmpty($server->id());
if ($server->name() == $dbName) {
++$match;
}
}
$this->assertEquals(1, $match);
}
/**
* @depends testListInstances
*/
public function testIsItAllWorthIt() {
$inst = $this->inst();
$maxAttempts = 5;
for($i = 0; $i < $maxAttempts; ++$i) {
$details = $inst->describe($this->dbId);
if ($details->status == 'ready') {
$dsn = $details->dsn();
break;
}
}
$this->assertNotEmpty($dsn);
$conn = new PDO($dsn, $this->credentials['user'], $this->credentials['pass']);
$affected = $conn->execute('SELECT 1');
$this->assertEquals(0, $affected);
unset($conn);
}
/**
* @depends testCreate
*/
public function testDelete() {
$match = 0;
$dbName = self::conf('hpcloud.dbaas.database');
$inst = $this->inst();
$inst->delete($this->dbId);
foreach ($instances['instances'] as $server) {
if ($server->name() == $dbName) {
++$match;
}
}
$this->assertEquals(0, $match);
}
}

View File

@@ -31,7 +31,10 @@ require_once 'test/TestCase.php';
use \HPCloud\Services\DBaaS\Snapshot;
class DBaaSSnapshotextends \HPCloud\Tests\TestCase {
/**
* @group dbaas
*/
class DBaaSSnapshot extends \HPCloud\Tests\TestCase {
public function testConstruct() {
}

View File

@@ -31,6 +31,9 @@ require_once 'test/TestCase.php';
use \HPCloud\Services\DBaaS;
/**
* @group dbaas
*/
class DBaaSTest extends \HPCloud\Tests\TestCase {
protected function dbaas() {
@@ -70,7 +73,7 @@ class DBaaSTest extends \HPCloud\Tests\TestCase {
public function testConstructor() {
$ident = $this->identity();
$dbaas = new DBaaS($ident->token(), self::$settings['hpcloud.dbaas.endpoint'], $ident->tenantName());
$dbaas = new DBaaS($ident->token(), self::conf('hpcloud.dbaas.endpoint'), $ident->tenantName());
$this->assertInstanceOf("\HPCloud\Services\DBaaS", $dbaas);
$this->assertEquals($ident->tenantName(), $dbaas->projectId());