]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Merge "Get volume from db again before updating it's status"
authorJenkins <jenkins@review.openstack.org>
Wed, 15 Apr 2015 05:21:30 +0000 (05:21 +0000)
committerGerrit Code Review <review@openstack.org>
Wed, 15 Apr 2015 05:21:30 +0000 (05:21 +0000)
1  2 
cinder/db/sqlalchemy/api.py
cinder/tests/test_volume.py
cinder/volume/manager.py

Simple merge
index 9571641eeeb2fdb0edaa0da954e17cb565250ff6,818d3deac2fad2c4ca3ee33a8ca6ef58d6154d2a..f14f8990bfa0ce172d878ce67c1ef07fc157a519
@@@ -4792,7 -4574,47 +4792,47 @@@ class CopyVolumeToImageTestCase(BaseVol
                                           self.image_meta)
  
          volume = db.volume_get(self.context, self.volume_id)
 -        self.assertEqual(volume['status'], 'available')
 +        self.assertEqual('available', volume['status'])
+     def test_copy_volume_to_image_instance_deleted(self):
+         # During uploading volume to image if instance is deleted,
+         # volume should be in available status.
+         self.image_meta['id'] = 'a440c04b-79fa-479c-bed1-0b816eaec379'
+         # Creating volume testdata
+         self.volume_attrs['instance_uuid'] = 'b21f957d-a72f-4b93-b5a5-' \
+                                              '45b1161abb02'
+         db.volume_create(self.context, self.volume_attrs)
+         # Storing unmocked db api function reference here, because we have to
+         # update volume status (set instance_uuid to None) before calling the
+         # 'volume_update_status_based_on_attached_instance_id' db api.
+         unmocked_db_api = db.volume_update_status_based_on_attachment
+         def mock_volume_update_after_upload(context, volume_id):
+             # First update volume and set 'instance_uuid' to None
+             # because after deleting instance, instance_uuid of volume is
+             # set to None
+             db.volume_update(context, volume_id, {'instance_uuid': None})
+             # Calling unmocked db api
+             unmocked_db_api(context, volume_id)
+         with mock.patch.object(
+                 db,
+                 'volume_update_status_based_on_attachment',
+                 side_effect=mock_volume_update_after_upload) as mock_update:
+             # Start test
+             self.volume.copy_volume_to_image(self.context,
+                                              self.volume_id,
+                                              self.image_meta)
+             # Check 'volume_update_status_after_copy_volume_to_image'
+             # is called 1 time
+             self.assertEqual(1, mock_update.call_count)
+         # Check volume status has changed to available because
+         # instance is deleted
+         volume = db.volume_get(self.context, self.volume_id)
+         self.assertEqual('available', volume['status'])
  
      def test_copy_volume_to_image_status_use(self):
          self.image_meta['id'] = 'a440c04b-79fa-479c-bed1-0b816eaec379'
index cf43b6518d136749b57f2bddde5d3aac744b477b,2dd0823d9e9928182f5b68d48caf013d84403edc..6574a1a57ddf8b79b6e00d0b3e27db89a0e49c8d
@@@ -960,14 -936,10 +960,10 @@@ class VolumeManager(manager.SchedulerDe
                  self._delete_image(context, image_meta['id'], image_service)
  
              with excutils.save_and_reraise_exception():
 -                payload['message'] = unicode(error)
 +                payload['message'] = six.text_type(error)
          finally:
-             if not volume['volume_attachment']:
-                 self.db.volume_update(context, volume_id,
-                                       {'status': 'available'})
-             else:
-                 self.db.volume_update(context, volume_id,
-                                       {'status': 'in-use'})
+             self.db.volume_update_status_based_on_attachment(context,
+                                                              volume_id)
  
      def _delete_image(self, context, image_id, image_service):
          """Deletes an image stuck in queued or saving state."""