From f9653481bee48f7d0b29e24d1efbf0472280ba45 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Thu, 8 Jan 2015 16:12:13 +0100 Subject: [PATCH 1/7] Add mock HTTP responses --- .../_response/LoadBalancers1.resp | 80 +++++++++++++++++++ .../_response/LoadBalancers2.resp | 80 +++++++++++++++++++ .../_response/LoadBalancers3.resp | 34 ++++++++ 3 files changed, 194 insertions(+) create mode 100644 tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp create mode 100644 tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp create mode 100644 tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp 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 From e5f57b5faef28fbdb72204928b47132696328da7 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Thu, 8 Jan 2015 16:13:22 +0100 Subject: [PATCH 2/7] Decouple the process of retrieving last element from setting marker --- lib/OpenCloud/Common/Collection/PaginatedIterator.php | 4 ++++ 1 file changed, 4 insertions(+) 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)) { From 9cd0db166d718fb4ab9e53f280f815c008326133 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Thu, 8 Jan 2015 16:13:39 +0100 Subject: [PATCH 3/7] Add new iterator to handle differences --- .../Collection/LoadBalancerIterator.php | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php diff --git a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php new file mode 100644 index 000000000..f554c6512 --- /dev/null +++ b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php @@ -0,0 +1,43 @@ +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')) { + // Save last element (we will need it for the next marker) + $this->nextElement = end($response); + + // Since we previously asked for n+1 elements, pop the unwanted element + array_pop($response); + reset($response); + } + + return $response; + } +} \ No newline at end of file From 3f69dfd76398cd446e4fb839c8622de8c9e921cc Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Thu, 8 Jan 2015 16:13:51 +0100 Subject: [PATCH 4/7] Implement into service and refactor tests --- lib/OpenCloud/LoadBalancer/Service.php | 12 ++++- .../Tests/LoadBalancer/ServiceTest.php | 48 ++++++++++++++----- tests/OpenCloud/Tests/OpenCloudTestCase.php | 13 ++--- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/lib/OpenCloud/LoadBalancer/Service.php b/lib/OpenCloud/LoadBalancer/Service.php index 93905a0d2..6f5052f2c 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('baseUrl' => $url, 'key.marker' => 'id'); + + return LoadBalancerIterator::factory($this, $options); } /** diff --git a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php index 6bd047064..2d01e2f93 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/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(); } From 622d76d436ee98fec854f77699f7bf5a8db37fd5 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Fri, 9 Jan 2015 11:25:08 +0100 Subject: [PATCH 5/7] Appease PSR-2 gods --- lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php | 2 +- tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php index f554c6512..d6326048e 100644 --- a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php +++ b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php @@ -40,4 +40,4 @@ public function parseResponseBody($body) return $response; } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php index 2d01e2f93..9beb0c620 100644 --- a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php +++ b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php @@ -79,7 +79,7 @@ public function test_Listing_Load_Balancers() // Check our assumptions $this->isCollection($lbs); - $this->assertEquals($ids, array(1,2,3,4,5)); + $this->assertEquals($ids, array(1, 2, 3, 4, 5)); } public function testBillableLoadBalancer() From 6895f8484bb8cbc855c9b3ea86fe1d1f5efc3bb3 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Fri, 9 Jan 2015 11:32:29 +0100 Subject: [PATCH 6/7] Attempt to fix 5.3 segfault --- phpunit.xml.dist | 5 +++++ 1 file changed, 5 insertions(+) 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 @@ + + + + + From 48e1df45489198b3812d97057a2b4c29fc897232 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Tue, 13 Jan 2015 12:36:20 +0100 Subject: [PATCH 7/7] Tweaks based on code review --- .../LoadBalancer/Collection/LoadBalancerIterator.php | 8 ++------ lib/OpenCloud/LoadBalancer/Service.php | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php index d6326048e..7febf1af3 100644 --- a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php +++ b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php @@ -30,12 +30,8 @@ public function parseResponseBody($body) $response = parent::parseResponseBody($body); if (count($response) >= $this->getOption('limit.page')) { - // Save last element (we will need it for the next marker) - $this->nextElement = end($response); - - // Since we previously asked for n+1 elements, pop the unwanted element - array_pop($response); - reset($response); + // 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 6f5052f2c..7f8d01f74 100644 --- a/lib/OpenCloud/LoadBalancer/Service.php +++ b/lib/OpenCloud/LoadBalancer/Service.php @@ -63,7 +63,7 @@ public function loadBalancerList($detail = true, array $filter = array()) $url->addPath(Resource\LoadBalancer::resourceName()); $url->setQuery($filter); - $options += array('baseUrl' => $url, 'key.marker' => 'id'); + $options = array_merge($options, array('baseUrl' => $url, 'key.marker' => 'id')); return LoadBalancerIterator::factory($this, $options); }