diff --git a/lib/OpenCloud/Common/Collection/PaginatedIterator.php b/lib/OpenCloud/Common/Collection/PaginatedIterator.php index a0628993d..ef827ac80 100644 --- a/lib/OpenCloud/Common/Collection/PaginatedIterator.php +++ b/lib/OpenCloud/Common/Collection/PaginatedIterator.php @@ -145,7 +145,11 @@ public function updateMarkerToCurrent() } $element = $this->elements[$this->position]; + $this->setMarkerFromElement($element); + } + protected function setMarkerFromElement($element) + { $key = $this->getOption('key.marker'); if (isset($element->$key)) { diff --git a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php new file mode 100644 index 000000000..7febf1af3 --- /dev/null +++ b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php @@ -0,0 +1,39 @@ +getQuery(); + $query['limit'] = $query['limit'] + 1; + $url->setQuery($query); + + return $url; + } + + public function updateMarkerToCurrent() + { + $this->setMarkerFromElement($this->nextElement); + } + + public function parseResponseBody($body) + { + $response = parent::parseResponseBody($body); + + if (count($response) >= $this->getOption('limit.page')) { + // Pop last element and save (we will need it for the next marker) + $this->nextElement = array_pop($response); + } + + return $response; + } +} diff --git a/lib/OpenCloud/LoadBalancer/Service.php b/lib/OpenCloud/LoadBalancer/Service.php index 93905a0d2..7f8d01f74 100644 --- a/lib/OpenCloud/LoadBalancer/Service.php +++ b/lib/OpenCloud/LoadBalancer/Service.php @@ -19,6 +19,7 @@ use OpenCloud\Common\Log\Logger; use OpenCloud\Common\Service\NovaService; +use OpenCloud\LoadBalancer\Collection\LoadBalancerIterator; /** * Class that encapsulates the Rackspace Cloud Load Balancers service @@ -51,11 +52,20 @@ public function loadBalancer($id = null) */ public function loadBalancerList($detail = true, array $filter = array()) { + $options = $this->makeResourceIteratorOptions($this->resolveResourceClass('LoadBalancer')); + + if (isset($filter['limit'])) { + $options['limit.page'] = $filter['limit']; + unset($filter['limit']); + } + $url = $this->getUrl(); $url->addPath(Resource\LoadBalancer::resourceName()); $url->setQuery($filter); - return $this->resourceList('LoadBalancer', $url); + $options = array_merge($options, array('baseUrl' => $url, 'key.marker' => 'id')); + + return LoadBalancerIterator::factory($this, $options); } /** diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cd44e77df..c2aeed2d4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -25,4 +25,9 @@ + + + + + diff --git a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php index 6bd047064..9beb0c620 100644 --- a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php +++ b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php @@ -27,15 +27,13 @@ namespace OpenCloud\Tests\LoadBalancer; -class ServiceTest extends \OpenCloud\Tests\OpenCloudTestCase -{ - private $service; - - public function setupObjects() - { - $this->service = $this->getClient()->loadBalancerService('cloudLoadBalancers', 'DFW', 'publicURL'); - } +use Guzzle\Http\Message\Response; +use Guzzle\Plugin\Mock\MockPlugin; +use OpenCloud\Rackspace; +use OpenCloud\Tests\MockSubscriber; +class ServiceTest extends LoadBalancerTestCase +{ public function test__construct() { $this->assertInstanceOf( @@ -52,12 +50,36 @@ public function testLoadBalancer() ); } - public function testLoadBalancerList() + public function test_Listing_Load_Balancers() { - $this->assertInstanceOf( - self::COLLECTION_CLASS, - $this->service->loadBalancerList() - ); + // Load JSON HTTP data + $authData = file_get_contents($this->getTestFilePath('Auth', './')); + $data1 = file_get_contents($this->getTestFilePath('LoadBalancers1')); + $data2 = file_get_contents($this->getTestFilePath('LoadBalancers2')); + $data3 = file_get_contents($this->getTestFilePath('LoadBalancers3')); + + // Populate mock response queue + $mock = new MockPlugin(); + $mock->addResponse(Response::fromMessage($authData)) + ->addResponse(Response::fromMessage($data1)) + ->addResponse(Response::fromMessage($data2)) + ->addResponse(Response::fromMessage($data3)); + + // We need to define our own setup because *jazz hands* + $client = $this->newClient(); + $client->addSubscriber($mock); + $service = $client->loadBalancerService(null, 'IAD'); + + // Ensure that a series of paginated calls return a holistic collection + $lbs = $service->loadBalancerList(false, array('limit' => 2)); + $ids = array(); + foreach ($lbs as $lb) { + $ids[] = $lb->id; + } + + // Check our assumptions + $this->isCollection($lbs); + $this->assertEquals($ids, array(1, 2, 3, 4, 5)); } public function testBillableLoadBalancer() diff --git a/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp new file mode 100644 index 000000000..1827f2b44 --- /dev/null +++ b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp @@ -0,0 +1,80 @@ +HTTP/1.1 200 OK +Status: 200 OK +Date: Thu, 28 Jul 2011 21:54:21 GMT +X-API-VERSION: 1.0.17 +Content-Type: application/json +Content-Length: 1975 + +{ + "loadBalancers":[ + { + "name":"lb-site1", + "id":1, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":3, + "virtualIps":[ + { + "id":403, + "address":"206.55.130.1", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site2", + "id":2, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site3", + "id":3, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + } + ] +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp new file mode 100644 index 000000000..2ab7b2381 --- /dev/null +++ b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp @@ -0,0 +1,80 @@ +HTTP/1.1 200 OK +Status: 200 OK +Date: Thu, 28 Jul 2011 21:54:21 GMT +X-API-VERSION: 1.0.17 +Content-Type: application/json +Content-Length: 1975 + +{ + "loadBalancers":[ + { + "name":"lb-site3", + "id":3, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site4", + "id":4, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site5", + "id":5, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + } + ] +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp new file mode 100644 index 000000000..554a4430d --- /dev/null +++ b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp @@ -0,0 +1,34 @@ +HTTP/1.1 200 OK +Status: 200 OK +Date: Thu, 28 Jul 2011 21:54:21 GMT +X-API-VERSION: 1.0.17 +Content-Type: application/json +Content-Length: 1975 + +{ + "loadBalancers":[ + { + "name":"lb-site5", + "id":5, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + } + ] +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/OpenCloudTestCase.php b/tests/OpenCloud/Tests/OpenCloudTestCase.php index 628881fbb..8d7582c1f 100644 --- a/tests/OpenCloud/Tests/OpenCloudTestCase.php +++ b/tests/OpenCloud/Tests/OpenCloudTestCase.php @@ -38,17 +38,10 @@ abstract class OpenCloudTestCase extends \PHPUnit_Framework_TestCase public function newClient() { - $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + return new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( 'username' => 'foo', 'apiKey' => 'bar' )); - - $client->addSubscriber(new MockSubscriber()); - //$client->addSubscriber(LogPlugin::getDebugPlugin()); - - $client->authenticate(); - - return $client; } public function getClient() @@ -59,6 +52,10 @@ public function getClient() public function setUp() { $this->client = $this->newClient(); + + $this->client->addSubscriber(new MockSubscriber()); + $this->client->authenticate(); + $this->setupObjects(); $this->handleMockSubscribers(); }