diff --git a/openstack/compute/v2/flavor.py b/openstack/compute/v2/flavor.py index 10975e3f9..e9671df4f 100644 --- a/openstack/compute/v2/flavor.py +++ b/openstack/compute/v2/flavor.py @@ -57,7 +57,7 @@ class Flavor(resource.Resource): #: The number of virtual CPUs this flavor offers. *Type: int* vcpus = resource.Body('vcpus', type=int, default=0) #: Size of the swap partitions. - swap = resource.Body('swap', default=0) + swap = resource.Body('swap', type=int, default=0) #: Size of the ephemeral data disk attached to this server. *Type: int* ephemeral = resource.Body('OS-FLV-EXT-DATA:ephemeral', type=int, default=0) #: ``True`` if this flavor is disabled, ``False`` if not. *Type: bool* diff --git a/openstack/resource.py b/openstack/resource.py index bfa39fa59..28c835dfb 100644 --- a/openstack/resource.py +++ b/openstack/resource.py @@ -83,7 +83,14 @@ def _convert_type(value, data_type, list_type=None): # and the AbsoluteLimits type for an example. if isinstance(value, dict): return data_type(**value) - return data_type(value) + try: + return data_type(value) + except ValueError: + # If we can not convert data to the expected type return empty + # instance of the expected type. + # This is necessary to handle issues like with flavor.swap where + # empty string means "0". + return data_type() class _BaseComponent: diff --git a/openstack/tests/fakes.py b/openstack/tests/fakes.py index 533aed706..1bf0bd705 100644 --- a/openstack/tests/fakes.py +++ b/openstack/tests/fakes.py @@ -70,7 +70,7 @@ def make_fake_flavor(flavor_id, name, ram=100, disk=1600, vcpus=24): u'os-flavor-access:is_public': True, u'ram': ram, u'rxtx_factor': 1.0, - u'swap': u'', + u'swap': 0, u'vcpus': vcpus, } diff --git a/openstack/tests/unit/cloud/test_caching.py b/openstack/tests/unit/cloud/test_caching.py index 579ae1b94..58f6489f5 100644 --- a/openstack/tests/unit/cloud/test_caching.py +++ b/openstack/tests/unit/cloud/test_caching.py @@ -26,6 +26,7 @@ from openstack.identity.v3 import project as _project from openstack.identity.v3 import user as _user from openstack.image.v2 import image as _image from openstack.network.v2 import port as _port +from openstack.test import fakes as _fakes from openstack.tests import fakes from openstack.tests.unit import base from openstack.tests.unit.cloud import test_port @@ -539,6 +540,7 @@ class TestMemoryCache(base.TestCase): mock_uri = '{endpoint}/flavors/detail?is_public=None'.format( endpoint=fakes.COMPUTE_ENDPOINT ) + flavors = list(_fakes.generate_fake_resources(_flavor.Flavor, count=2)) uris_to_mock = [ dict( @@ -555,7 +557,7 @@ class TestMemoryCache(base.TestCase): validate=dict( headers={'OpenStack-API-Version': 'compute 2.53'} ), - json={'flavors': fakes.FAKE_FLAVOR_LIST}, + json={'flavors': flavors}, ), ] self.use_compute_discovery() @@ -568,7 +570,7 @@ class TestMemoryCache(base.TestCase): self.cloud.list_flavors.invalidate(self.cloud) self.assertResourceListEqual( - self.cloud.list_flavors(), fakes.FAKE_FLAVOR_LIST, _flavor.Flavor + self.cloud.list_flavors(), flavors, _flavor.Flavor ) self.assert_calls() diff --git a/openstack/tests/unit/compute/v2/test_flavor.py b/openstack/tests/unit/compute/v2/test_flavor.py index d3bc42350..35dcdff4b 100644 --- a/openstack/tests/unit/compute/v2/test_flavor.py +++ b/openstack/tests/unit/compute/v2/test_flavor.py @@ -91,6 +91,12 @@ class TestFlavor(base.TestCase): ) self.assertEqual(BASIC_EXAMPLE['rxtx_factor'], sot.rxtx_factor) + def test_make_basic_swap(self): + sot = flavor.Flavor(id=IDENTIFIER, swap="") + self.assertEqual(0, sot.swap) + sot1 = flavor.Flavor(id=IDENTIFIER, swap=0) + self.assertEqual(0, sot1.swap) + def test_make_defaults(self): sot = flavor.Flavor(**DEFAULTS_EXAMPLE) self.assertEqual(DEFAULTS_EXAMPLE['original_name'], sot.name)