From fd2c41c69715ba39588c18224aef4e8734ed3ce1 Mon Sep 17 00:00:00 2001 From: Artem Goncharov Date: Wed, 7 Jun 2023 16:35:31 +0200 Subject: [PATCH] fix flavor.swap attribute type swap attribute of flavor is expected to be int. It is already checked as int in compute unittests, but not once returned as a fake. Change-Id: I4da810cd9828374cebb2a120cce6a8d55f182ea9 --- openstack/compute/v2/flavor.py | 2 +- openstack/resource.py | 9 ++++++++- openstack/tests/fakes.py | 2 +- openstack/tests/unit/cloud/test_caching.py | 6 ++++-- openstack/tests/unit/compute/v2/test_flavor.py | 6 ++++++ 5 files changed, 20 insertions(+), 5 deletions(-) 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 3443f584e..deff1f009 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 a4a7ece8e..9a208462b 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 d137d15ab..92ae2b15d 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)