You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by qu...@apache.org on 2017/12/14 17:46:29 UTC
[1/3] libcloud git commit: added location parameter to driver's
list_sizes method. This makes it possible to get location specific price
Repository: libcloud
Updated Branches:
refs/heads/trunk dcb0cef8e -> ab84b0304
added location parameter to driver's list_sizes method. This makes it possible to get location specific price
Signed-off-by: Quentin Pradet <qu...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/30d6d0b8
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/30d6d0b8
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/30d6d0b8
Branch: refs/heads/trunk
Commit: 30d6d0b88a174802e24e5eda8b32437c39b6df48
Parents: 721a83a
Author: Mika Lackman <mi...@upcloud.com>
Authored: Thu Dec 14 14:21:41 2017 +0200
Committer: Quentin Pradet <qu...@apache.org>
Committed: Thu Dec 14 21:40:32 2017 +0400
----------------------------------------------------------------------
libcloud/common/upcloud.py | 24 ++++++++++---------
libcloud/compute/drivers/upcloud.py | 23 ++++++++++--------
libcloud/test/common/test_upcloud.py | 24 +++++++------------
libcloud/test/compute/test_upcloud.py | 38 ++++--------------------------
4 files changed, 39 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/30d6d0b8/libcloud/common/upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/common/upcloud.py b/libcloud/common/upcloud.py
index c3fc6f7..de6f794 100644
--- a/libcloud/common/upcloud.py
+++ b/libcloud/common/upcloud.py
@@ -211,26 +211,28 @@ class PlanPrice(object):
def __init__(self, zone_prices):
self._zone_prices = zone_prices
- def get_prices_in_zones(self, plan_name):
+ def get_price(self, plan_name, location=None):
"""
- Returns list of prices in different zones,
- [{'zone_id': 'uk-lon1', 'price': 1.588'},...]
- If plan is not found in a zone, price is set to None.
+ Returns the plan's price in location. If location
+ is not provided returns None
:param plan_name: Name of the plan
:type plan_name: ```str```
- rtype: ``list``
+ :param location: Location, which price is returned (optional)
+ :type location: :class:`.NodeLocation`
+
+
+ rtype: ``float``
"""
+ if location is None:
+ return None
server_plan_name = 'server_plan_' + plan_name
- prices = []
-
for zone_price in self._zone_prices:
- zone_id = zone_price['name']
- price = zone_price.get(server_plan_name, {}).get('price')
- prices.append({'zone_id': zone_id, 'price': price})
- return prices
+ if zone_price['name'] == location.id:
+ return zone_price.get(server_plan_name, {}).get('price')
+ return None
class _LoginUser(object):
http://git-wip-us.apache.org/repos/asf/libcloud/blob/30d6d0b8/libcloud/compute/drivers/upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/upcloud.py b/libcloud/compute/drivers/upcloud.py
index e0357fc..75a0a9e 100644
--- a/libcloud/compute/drivers/upcloud.py
+++ b/libcloud/compute/drivers/upcloud.py
@@ -106,20 +106,22 @@ class UpcloudDriver(NodeDriver):
response = self.connection.request('1.2/zone')
return self._to_node_locations(response.object['zones']['zone'])
- def list_sizes(self):
+ def list_sizes(self, location=None):
"""
List available plans
- Note: Node.price will be always None, because the pricing depends,
- where the Node is hosted. Node.extra['zones'] will contain
- pricing for different hosting zones.
+ :param location: Location of the deployement. Price depends on
+ location. lf location is not given or price not found for
+ location, price will be None (optional)
+ :type location: :class:`.NodeLocation`
:rtype: ``list`` of :class:`NodeSize`
"""
prices_response = self.connection.request('1.2/price')
response = self.connection.request('1.2/plan')
return self._to_node_sizes(response.object['plans']['plan'],
- prices_response.object['prices']['zone'])
+ prices_response.object['prices']['zone'],
+ location)
def list_images(self):
"""
@@ -270,18 +272,19 @@ class UpcloudDriver(NodeDriver):
Zone_id format [country]_[city][number], like fi_hel1"""
return zone_id.split('-')[0].upper()
- def _to_node_sizes(self, plans, prices):
+ def _to_node_sizes(self, plans, prices, location):
plan_price = PlanPrice(prices)
- return [self._construct_node_size(plan, plan_price) for plan in plans]
+ return [self._to_node_size(plan, plan_price, location)
+ for plan in plans]
- def _construct_node_size(self, plan, plan_price):
+ def _to_node_size(self, plan, plan_price, location):
extra = self._copy_dict(('core_number', 'storage_tier'), plan)
- extra['zones'] = plan_price.get_prices_in_zones(plan['name'])
return NodeSize(id=plan['name'], name=plan['name'],
ram=plan['memory_amount'],
disk=plan['storage_size'],
bandwidth=plan['public_traffic_out'],
- price=None, driver=self,
+ price=plan_price.get_price(plan['name'], location),
+ driver=self,
extra=extra)
def _to_node_images(self, images):
http://git-wip-us.apache.org/repos/asf/libcloud/blob/30d6d0b8/libcloud/test/common/test_upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/test/common/test_upcloud.py b/libcloud/test/common/test_upcloud.py
index 886a01a..4a2acb1 100644
--- a/libcloud/test/common/test_upcloud.py
+++ b/libcloud/test/common/test_upcloud.py
@@ -265,27 +265,21 @@ class TestUpcloudNodeDestroyer(unittest.TestCase):
class TestPlanPrice(unittest.TestCase):
- def test_zone_prices(self):
+ def setUp(self):
prices = [{'name': 'uk-lon1', 'server_plan_1xCPU-1GB': {'amount': 1, 'price': 1.488}},
{'name': 'fi-hel1', 'server_plan_1xCPU-1GB': {'amount': 1, 'price': 1.588}}]
- pp = PlanPrice(prices)
-
- zone_prices = pp.get_prices_in_zones('1xCPU-1GB')
+ self.pp = PlanPrice(prices)
- self.assertEqual(len(zone_prices), 2)
- self.assertIn({'zone_id': 'uk-lon1', 'price': 1.488}, zone_prices)
- self.assertIn({'zone_id': 'fi-hel1', 'price': 1.588}, zone_prices)
+ def test_zone_prices(self):
+ location = NodeLocation(id='fi-hel1', name='Helsinki #1', country='FI', driver=None)
+ self.assertEqual(self.pp.get_price('1xCPU-1GB', location), 1.588)
def test_plan_not_found_in_zone(self):
- prices = [{'name': 'uk-lon1', 'server_plan_1xCPU-1GB': {'amount': 1, 'price': 1.488}},
- {'name': 'fi-hel1', 'server_plan_4xCPU-1GB': {'amount': 1, 'price': 1.588}}]
- pp = PlanPrice(prices)
-
- zone_prices = pp.get_prices_in_zones('1xCPU-1GB')
+ location = NodeLocation(id='no_such_location', name='', country='', driver=None)
+ self.assertEqual(self.pp.get_price('1xCPU-1GB', location), None)
- self.assertEqual(len(zone_prices), 2)
- self.assertIn({'zone_id': 'uk-lon1', 'price': 1.488}, zone_prices)
- self.assertIn({'zone_id': 'fi-hel1', 'price': None}, zone_prices)
+ def test_no_location_given(self):
+ self.assertEqual(self.pp.get_price('1xCPU-1GB'), None)
if __name__ == '__main__':
http://git-wip-us.apache.org/repos/asf/libcloud/blob/30d6d0b8/libcloud/test/compute/test_upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_upcloud.py b/libcloud/test/compute/test_upcloud.py
index 56aebe2..041582f 100644
--- a/libcloud/test/compute/test_upcloud.py
+++ b/libcloud/test/compute/test_upcloud.py
@@ -82,48 +82,18 @@ class UpcloudDriverTests(LibcloudTestCase):
self.assert_object(expected_node_location, objects=locations)
def test_list_sizes(self):
- sizes = self.driver.list_sizes()
+ location = NodeLocation(id='fi-hel1', name='Helsinki #1', country='FI', driver=self.driver)
+ sizes = self.driver.list_sizes(location)
self.assertTrue(len(sizes) >= 1)
- expected_zones = [
- {
- 'zone_id': 'de-fra1',
- 'price': 1.488
- },
- {
- 'zone_id': 'fi-dev2',
- 'price': 2.232
- },
- {
- 'zone_id': 'fi-hel1',
- 'price': 2.232
- },
- {
- 'zone_id': 'nl-ams1',
- 'price': 1.488
- },
- {
- 'zone_id': 'sg-sin1',
- 'price': 1.488
- },
- {
- 'zone_id': 'uk-lon1',
- 'price': 1.488
- },
- {
- 'zone_id': 'us-chi1',
- 'price': 1.488
- }
- ]
expected_node_size = NodeSize(id='1xCPU-1GB',
name='1xCPU-1GB',
ram=1024,
disk=30,
bandwidth=2048,
- price=None,
+ price=2.232,
driver=self.driver,
extra={'core_number': 1,
- 'storage_tier': 'maxiops',
- 'zones': expected_zones})
+ 'storage_tier': 'maxiops'})
self.assert_object(expected_node_size, objects=sizes)
def test_list_images(self):
[3/3] libcloud git commit: Add changes for #1152
Posted by qu...@apache.org.
Add changes for #1152
Closes #1152
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/ab84b030
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/ab84b030
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/ab84b030
Branch: refs/heads/trunk
Commit: ab84b03042a8f85dc5201ae1a8317ec1fc5a7950
Parents: 30d6d0b
Author: Quentin Pradet <qu...@apache.org>
Authored: Thu Dec 14 21:42:04 2017 +0400
Committer: Quentin Pradet <qu...@apache.org>
Committed: Thu Dec 14 21:42:04 2017 +0400
----------------------------------------------------------------------
CHANGES.rst | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ab84b030/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 37ea3ac..0f19b18 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -57,6 +57,9 @@ Compute
(LIBCLOUD-951, LIBCLOUD-953, GITHUB-1123, GITHUB-1125)
[Mika Lackman]
+- [UpCloud] Add pricing information to list_sizes (LIBCLOUD-969, GITHUB-1152)
+ [Mika Lackman]
+
- [ARM] Delete VHDs more reliably in destroy_node(), raise exception on unhandled errors
(GITHUB-1120)
[Lucas Di Pentima]
[2/3] libcloud git commit: [LIBCLOUD-969] Add pricing information to
UpCloud's driver list_sizes
Posted by qu...@apache.org.
[LIBCLOUD-969] Add pricing information to UpCloud's driver list_sizes
Signed-off-by: Quentin Pradet <qu...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/721a83ae
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/721a83ae
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/721a83ae
Branch: refs/heads/trunk
Commit: 721a83aec40894bd8e3be03cb5e4cea0fd278696
Parents: dcb0cef
Author: Mika Lackman <mi...@upcloud.com>
Authored: Mon Dec 11 11:04:16 2017 +0200
Committer: Quentin Pradet <qu...@apache.org>
Committed: Thu Dec 14 21:40:32 2017 +0400
----------------------------------------------------------------------
libcloud/common/upcloud.py | 34 +
libcloud/compute/drivers/upcloud.py | 17 +-
libcloud/test/common/test_upcloud.py | 26 +
.../compute/fixtures/upcloud/api_1_2_price.json | 683 +++++++++++++++++++
libcloud/test/compute/test_upcloud.py | 53 +-
5 files changed, 804 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/721a83ae/libcloud/common/upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/common/upcloud.py b/libcloud/common/upcloud.py
index 05fb5c2..c3fc6f7 100644
--- a/libcloud/common/upcloud.py
+++ b/libcloud/common/upcloud.py
@@ -199,6 +199,40 @@ class UpcloudNodeOperations(object):
method='DELETE')
+class PlanPrice(object):
+ """
+ Helper class to construct plan price in different zones
+
+ :param zone_prices: List of prices in different zones in UpCloud
+ :type zone_prices: ```list```
+
+ """
+
+ def __init__(self, zone_prices):
+ self._zone_prices = zone_prices
+
+ def get_prices_in_zones(self, plan_name):
+ """
+ Returns list of prices in different zones,
+ [{'zone_id': 'uk-lon1', 'price': 1.588'},...]
+ If plan is not found in a zone, price is set to None.
+
+ :param plan_name: Name of the plan
+ :type plan_name: ```str```
+
+ rtype: ``list``
+ """
+ server_plan_name = 'server_plan_' + plan_name
+
+ prices = []
+
+ for zone_price in self._zone_prices:
+ zone_id = zone_price['name']
+ price = zone_price.get(server_plan_name, {}).get('price')
+ prices.append({'zone_id': zone_id, 'price': price})
+ return prices
+
+
class _LoginUser(object):
def __init__(self, user_id, auth=None):
http://git-wip-us.apache.org/repos/asf/libcloud/blob/721a83ae/libcloud/compute/drivers/upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/upcloud.py b/libcloud/compute/drivers/upcloud.py
index 3d98d2f..e0357fc 100644
--- a/libcloud/compute/drivers/upcloud.py
+++ b/libcloud/compute/drivers/upcloud.py
@@ -27,6 +27,7 @@ from libcloud.common.types import InvalidCredsError
from libcloud.common.upcloud import UpcloudCreateNodeRequestBody
from libcloud.common.upcloud import UpcloudNodeDestroyer
from libcloud.common.upcloud import UpcloudNodeOperations
+from libcloud.common.upcloud import PlanPrice
class UpcloudResponse(JsonResponse):
@@ -109,10 +110,16 @@ class UpcloudDriver(NodeDriver):
"""
List available plans
+ Note: Node.price will be always None, because the pricing depends,
+ where the Node is hosted. Node.extra['zones'] will contain
+ pricing for different hosting zones.
+
:rtype: ``list`` of :class:`NodeSize`
"""
+ prices_response = self.connection.request('1.2/price')
response = self.connection.request('1.2/plan')
- return self._to_node_sizes(response.object['plans']['plan'])
+ return self._to_node_sizes(response.object['plans']['plan'],
+ prices_response.object['prices']['zone'])
def list_images(self):
"""
@@ -263,11 +270,13 @@ class UpcloudDriver(NodeDriver):
Zone_id format [country]_[city][number], like fi_hel1"""
return zone_id.split('-')[0].upper()
- def _to_node_sizes(self, plans):
- return [self._construct_node_size(plan) for plan in plans]
+ def _to_node_sizes(self, plans, prices):
+ plan_price = PlanPrice(prices)
+ return [self._construct_node_size(plan, plan_price) for plan in plans]
- def _construct_node_size(self, plan):
+ def _construct_node_size(self, plan, plan_price):
extra = self._copy_dict(('core_number', 'storage_tier'), plan)
+ extra['zones'] = plan_price.get_prices_in_zones(plan['name'])
return NodeSize(id=plan['name'], name=plan['name'],
ram=plan['memory_amount'],
disk=plan['storage_size'],
http://git-wip-us.apache.org/repos/asf/libcloud/blob/721a83ae/libcloud/test/common/test_upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/test/common/test_upcloud.py b/libcloud/test/common/test_upcloud.py
index 37bef0d..886a01a 100644
--- a/libcloud/test/common/test_upcloud.py
+++ b/libcloud/test/common/test_upcloud.py
@@ -20,6 +20,7 @@ from mock import Mock, call
from libcloud.common.upcloud import UpcloudCreateNodeRequestBody, UpcloudNodeDestroyer, UpcloudNodeOperations
from libcloud.common.upcloud import _StorageDevice
from libcloud.common.upcloud import UpcloudTimeoutException
+from libcloud.common.upcloud import PlanPrice
from libcloud.compute.base import NodeImage, NodeSize, NodeLocation, NodeAuthSSHKey
from libcloud.test import unittest
@@ -262,5 +263,30 @@ class TestUpcloudNodeDestroyer(unittest.TestCase):
self.assertTrue(self.destroyer.destroy_node(1))
+class TestPlanPrice(unittest.TestCase):
+
+ def test_zone_prices(self):
+ prices = [{'name': 'uk-lon1', 'server_plan_1xCPU-1GB': {'amount': 1, 'price': 1.488}},
+ {'name': 'fi-hel1', 'server_plan_1xCPU-1GB': {'amount': 1, 'price': 1.588}}]
+ pp = PlanPrice(prices)
+
+ zone_prices = pp.get_prices_in_zones('1xCPU-1GB')
+
+ self.assertEqual(len(zone_prices), 2)
+ self.assertIn({'zone_id': 'uk-lon1', 'price': 1.488}, zone_prices)
+ self.assertIn({'zone_id': 'fi-hel1', 'price': 1.588}, zone_prices)
+
+ def test_plan_not_found_in_zone(self):
+ prices = [{'name': 'uk-lon1', 'server_plan_1xCPU-1GB': {'amount': 1, 'price': 1.488}},
+ {'name': 'fi-hel1', 'server_plan_4xCPU-1GB': {'amount': 1, 'price': 1.588}}]
+ pp = PlanPrice(prices)
+
+ zone_prices = pp.get_prices_in_zones('1xCPU-1GB')
+
+ self.assertEqual(len(zone_prices), 2)
+ self.assertIn({'zone_id': 'uk-lon1', 'price': 1.488}, zone_prices)
+ self.assertIn({'zone_id': 'fi-hel1', 'price': None}, zone_prices)
+
+
if __name__ == '__main__':
sys.exit(unittest.main())
http://git-wip-us.apache.org/repos/asf/libcloud/blob/721a83ae/libcloud/test/compute/fixtures/upcloud/api_1_2_price.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/upcloud/api_1_2_price.json b/libcloud/test/compute/fixtures/upcloud/api_1_2_price.json
new file mode 100644
index 0000000..3b9d3c6
--- /dev/null
+++ b/libcloud/test/compute/fixtures/upcloud/api_1_2_price.json
@@ -0,0 +1,683 @@
+{
+ "prices" : {
+ "zone" : [
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "de-fra1",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.12
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.14
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 47.619
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 1.488
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 95.2381
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 2.976
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 5.952
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 11.905
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 23.8095
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ },
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_hdd" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "fi-dev2",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.24
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.34
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 107.1429
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 2.232
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 142.8571
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 4.464
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 8.928
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 17.857
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 35.7143
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_hdd" : {
+ "amount" : 1,
+ "price" : 0.0145
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ },
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_hdd" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_ssd" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "fi-hel1",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.24
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.34
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 107.1429
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 2.232
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 142.8571
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 4.464
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 8.928
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 17.857
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 35.7143
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_hdd" : {
+ "amount" : 1,
+ "price" : 0.0145
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_ssd" : {
+ "amount" : 1,
+ "price" : 0.056
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ },
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "nl-ams1",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.12
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.14
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 47.619
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 1.488
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 95.2381
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 2.976
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 5.952
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 11.905
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 23.8095
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ },
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "sg-sin1",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.12
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.14
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 47.619
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 1.488
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 95.2381
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 2.976
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 5.952
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 11.905
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 23.8095
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ },
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_hdd" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_ssd" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "uk-lon1",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.12
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.14
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 47.619
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 1.488
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 95.2381
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 2.976
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 5.952
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 11.905
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 23.8095
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_hdd" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_ssd" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ },
+ {
+ "firewall" : {
+ "amount" : 1,
+ "price" : 0.56
+ },
+ "io_request_backup" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "io_request_maxiops" : {
+ "amount" : 1000000,
+ "price" : 0
+ },
+ "ipv4_address" : {
+ "amount" : 1,
+ "price" : 0.336
+ },
+ "ipv6_address" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "name" : "us-chi1",
+ "public_ipv4_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv4_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "public_ipv6_bandwidth_in" : {
+ "amount" : 1,
+ "price" : 0
+ },
+ "public_ipv6_bandwidth_out" : {
+ "amount" : 1,
+ "price" : 5.6
+ },
+ "server_core" : {
+ "amount" : 1,
+ "price" : 1.12
+ },
+ "server_memory" : {
+ "amount" : 256,
+ "price" : 0.14
+ },
+ "server_plan_12xCPU-32GB" : {
+ "amount" : 1,
+ "price" : 47.619
+ },
+ "server_plan_16xCPU-48GB" : {
+ "amount" : 1,
+ "price" : 71.4286
+ },
+ "server_plan_1xCPU-1GB" : {
+ "amount" : 1,
+ "price" : 1.488
+ },
+ "server_plan_20xCPU-64GB" : {
+ "amount" : 1,
+ "price" : 95.2381
+ },
+ "server_plan_2xCPU-2GB" : {
+ "amount" : 1,
+ "price" : 2.976
+ },
+ "server_plan_4xCPU-4GB" : {
+ "amount" : 1,
+ "price" : 5.952
+ },
+ "server_plan_6xCPU-8GB" : {
+ "amount" : 1,
+ "price" : 11.905
+ },
+ "server_plan_8xCPU-16GB" : {
+ "amount" : 1,
+ "price" : 23.8095
+ },
+ "storage_backup" : {
+ "amount" : 1,
+ "price" : 0.0078
+ },
+ "storage_maxiops" : {
+ "amount" : 1,
+ "price" : 0.031
+ },
+ "storage_template" : {
+ "amount" : 1,
+ "price" : 0.031
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/721a83ae/libcloud/test/compute/test_upcloud.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_upcloud.py b/libcloud/test/compute/test_upcloud.py
index 951ee29..56aebe2 100644
--- a/libcloud/test/compute/test_upcloud.py
+++ b/libcloud/test/compute/test_upcloud.py
@@ -35,7 +35,8 @@ class UpcloudPersistResponse(UpcloudResponse):
def parse_body(self):
import os
- path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.pardir, 'compute', 'fixtures', 'upcloud'))
+ path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.pardir,
+ 'compute', 'fixtures', 'upcloud'))
filename = 'api' + self.request.path_url.replace('/', '_').replace('.', '_') + '.json'
filename = os.path.join(path, filename)
if not os.path.exists(filename):
@@ -83,6 +84,36 @@ class UpcloudDriverTests(LibcloudTestCase):
def test_list_sizes(self):
sizes = self.driver.list_sizes()
self.assertTrue(len(sizes) >= 1)
+ expected_zones = [
+ {
+ 'zone_id': 'de-fra1',
+ 'price': 1.488
+ },
+ {
+ 'zone_id': 'fi-dev2',
+ 'price': 2.232
+ },
+ {
+ 'zone_id': 'fi-hel1',
+ 'price': 2.232
+ },
+ {
+ 'zone_id': 'nl-ams1',
+ 'price': 1.488
+ },
+ {
+ 'zone_id': 'sg-sin1',
+ 'price': 1.488
+ },
+ {
+ 'zone_id': 'uk-lon1',
+ 'price': 1.488
+ },
+ {
+ 'zone_id': 'us-chi1',
+ 'price': 1.488
+ }
+ ]
expected_node_size = NodeSize(id='1xCPU-1GB',
name='1xCPU-1GB',
ram=1024,
@@ -91,7 +122,8 @@ class UpcloudDriverTests(LibcloudTestCase):
price=None,
driver=self.driver,
extra={'core_number': 1,
- 'storage_tier': 'maxiops'})
+ 'storage_tier': 'maxiops',
+ 'zones': expected_zones})
self.assert_object(expected_node_size, objects=sizes)
def test_list_images(self):
@@ -101,7 +133,7 @@ class UpcloudDriverTests(LibcloudTestCase):
name='Windows Server 2003 R2 Standard (CD 1)',
driver=self.driver,
extra={'access': 'public',
- 'licence': 0,
+ 'license': 0,
'size': 1,
'state': 'online',
'type': 'cdrom'})
@@ -189,8 +221,15 @@ class UpcloudDriverTests(LibcloudTestCase):
return expected_data == actual_data
def dicts_equals(self, d1, d2):
- """Assumes dicts to contain only hashable types"""
- return set(d1.values()) == set(d2.values())
+ dict_keys_same = set(d1.keys()) == set(d2.keys())
+ if not dict_keys_same:
+ return False
+
+ for key in d1.keys():
+ if d1[key] != d2[key]:
+ return False
+
+ return True
class UpcloudMockHttp(MockHttp):
@@ -219,6 +258,10 @@ class UpcloudMockHttp(MockHttp):
body = self.fixtures.load('api_1_2_storage_template.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _1_2_price(self, method, url, body, headers):
+ body = self.fixtures.load('api_1_2_price.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _1_2_server(self, method, url, body, headers):
if method == 'POST':
dbody = json.loads(body)