diff --git a/shade/meta.py b/shade/meta.py index c2d492bf2..aac20f113 100644 --- a/shade/meta.py +++ b/shade/meta.py @@ -334,17 +334,28 @@ def obj_to_dict(obj): """ if obj is None: return None - elif type(obj) == munch.Munch or hasattr(obj, 'mock_add_spec'): + elif isinstance(obj, munch.Munch) or hasattr(obj, 'mock_add_spec'): # If we obj_to_dict twice, don't fail, just return the munch # Also, don't try to modify Mock objects - that way lies madness return obj - elif type(obj) == dict: - return munch.Munch(obj) + elif hasattr(obj, '_shadeunittest'): + # Hook for unittesting + instance = munch.Munch() elif hasattr(obj, 'schema') and hasattr(obj, 'validate'): # It's a warlock return warlock_to_dict(obj) + elif isinstance(obj, dict): + # The new request-id tracking spec: + # https://specs.openstack.org/openstack/nova-specs/specs/juno/approved/log-request-id-mappings.html + # adds a request-ids attribute to returned objects. It does this even + # with dicts, which now become dict subclasses. So we want to convert + # the dict we get, but we also want it to fall through to object + # attribute processing so that we can also get the request_ids + # data into our resulting object. + instance = munch.Munch(obj) + else: + instance = munch.Munch() - instance = munch.Munch() for key in dir(obj): value = getattr(obj, key) if isinstance(value, NON_CALLABLES) and not key.startswith('_'): diff --git a/shade/tests/functional/test_volume.py b/shade/tests/functional/test_volume.py index 11b4f4ece..bcf2dfc04 100644 --- a/shade/tests/functional/test_volume.py +++ b/shade/tests/functional/test_volume.py @@ -45,13 +45,14 @@ class TestVolume(base.TestCase): display_name=snapshot_name ) - self.assertIn(volume, self.cloud.list_volumes()) - self.assertIn(snapshot, self.cloud.list_volume_snapshots()) - self.assertEqual(snapshot, - self.cloud.get_volume_snapshot( - snapshot['display_name'])) - self.assertEqual(snapshot, - self.cloud.get_volume_snapshot_by_id(snapshot['id'])) + volume_ids = [v['id'] for v in self.cloud.list_volumes()] + self.assertIn(volume['id'], volume_ids) + + snapshot_ids = [s['id'] for s in self.cloud.list_volume_snapshots()] + self.assertIn(snapshot['id'], snapshot_ids) + + ret_snapshot = self.cloud.get_volume_snapshot_by_id(snapshot['id']) + self.assertEqual(snapshot['id'], ret_snapshot['id']) self.cloud.delete_volume_snapshot(snapshot_name, wait=True) self.cloud.delete_volume(volume_name, wait=True) @@ -59,8 +60,8 @@ class TestVolume(base.TestCase): def cleanup(self, volume_name, snapshot_name): volume = self.cloud.get_volume(volume_name) snapshot = self.cloud.get_volume_snapshot(snapshot_name) - if volume: - self.cloud.delete_volume(volume_name) - + # Need to delete snapshots before volumes if snapshot: self.cloud.delete_volume_snapshot(snapshot_name) + if volume: + self.cloud.delete_volume(volume_name) diff --git a/shade/tests/unit/test_caching.py b/shade/tests/unit/test_caching.py index 2a080ad71..5abe40638 100644 --- a/shade/tests/unit/test_caching.py +++ b/shade/tests/unit/test_caching.py @@ -394,6 +394,9 @@ class TestMemoryCache(base.TestCase): id = '99' name = '99 name' + def _shadeunittest(self): + pass + fake_image = FakeImage() fake_image.update({ 'id': '99', @@ -407,6 +410,9 @@ class TestMemoryCache(base.TestCase): status = 'success' result = {'image_id': '99'} + def _shadeunittest(self): + pass + fake_task = FakeTask() fake_task.update({ 'id': '100', @@ -439,6 +445,10 @@ class TestMemoryCache(base.TestCase): id = 1 status = 'active' name = 'None Test Image' + + def _shadeunittest(self): + pass + fi = FakeImage(id=FakeImage.id, status=FakeImage.status, name=FakeImage.name) glance_mock.images.list.return_value = [fi] diff --git a/shade/tests/unit/test_meta.py b/shade/tests/unit/test_meta.py index 77688adfa..faf06e462 100644 --- a/shade/tests/unit/test_meta.py +++ b/shade/tests/unit/test_meta.py @@ -472,6 +472,16 @@ class TestMeta(testtools.TestCase): self.assertTrue(hasattr(cloud_dict, 'name')) self.assertEquals(cloud_dict.name, cloud_dict['name']) + def test_obj_to_dict_subclass(self): + class FakeObjDict(dict): + additional = 1 + obj = FakeObjDict(foo='bar') + obj_dict = meta.obj_to_dict(obj) + self.assertIn('additional', obj_dict) + self.assertIn('foo', obj_dict) + self.assertEquals(obj_dict['additional'], 1) + self.assertEquals(obj_dict['foo'], 'bar') + def test_warlock_to_dict(self): schema = { 'name': 'Test',