Built out unit tests and most of functionality for Instance.
This commit is contained in:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user