Merge lp:~verterok/ubuntuone-client/fix-583412 into lp:ubuntuone-client

Proposed by Guillermo Gonzalez
Status: Merged
Approved by: Stuart Colville
Approved revision: 527
Merged at revision: 528
Proposed branch: lp:~verterok/ubuntuone-client/fix-583412
Merge into: lp:ubuntuone-client
Diff against target: 289 lines (+81/-31)
5 files modified
tests/syncdaemon/test_dbus.py (+33/-6)
tests/syncdaemon/test_vm.py (+8/-0)
ubuntuone/syncdaemon/dbus_interface.py (+16/-11)
ubuntuone/syncdaemon/filesystem_manager.py (+2/-1)
ubuntuone/syncdaemon/volume_manager.py (+22/-13)
To merge this branch: bzr merge lp:~verterok/ubuntuone-client/fix-583412
Reviewer Review Type Date Requested Status
Rodrigo Moya (community) Approve
Rick McBride (community) Approve
Review via email: mp+26621@code.launchpad.net

Commit message

Fix dbus_interface error handling in Folders.delete (and Shares.delete_share) when the volume_id is invalid.

Description of the change

Fix syncdaemon dbus interface when Folders.delete (or Shares.delete_share) is called with an invalid udf id, now the correct error signal is fired.

To post a comment you must log in.
Revision history for this message
Rick McBride (rmcbride) wrote :

Cool!

review: Approve
Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

Looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'tests/syncdaemon/test_dbus.py'
--- tests/syncdaemon/test_dbus.py 2010-05-19 19:57:54 +0000
+++ tests/syncdaemon/test_dbus.py 2010-06-02 18:22:20 +0000
@@ -37,7 +37,12 @@
37 DBUS_IFACE_PUBLIC_FILES_NAME,37 DBUS_IFACE_PUBLIC_FILES_NAME,
38 EventListener,38 EventListener,
39)39)
40from ubuntuone.syncdaemon.volume_manager import Share, Shared, UDF40from ubuntuone.syncdaemon.volume_manager import (
41 Share,
42 Shared,
43 UDF,
44 VolumeDoesNotExist,
45)
41from ubuntuone.syncdaemon.tools import DBusClient46from ubuntuone.syncdaemon.tools import DBusClient
42from ubuntuone.syncdaemon import event_queue, states, main, config47from ubuntuone.syncdaemon import event_queue, states, main, config
43from contrib.testing.testcase import (48from contrib.testing.testcase import (
@@ -1004,7 +1009,7 @@
1004 n_bytes_read=10,1009 n_bytes_read=10,
1005 deflated_size=20)1010 deflated_size=20)
1006 return d1011 return d
1007 1012
1008 def test_download_finished(self):1013 def test_download_finished(self):
1009 """ Test the DBus signals in Status """1014 """ Test the DBus signals in Status """
1010 a_dir = os.path.join(self.root_dir, u'ñoño'.encode('utf-8'))1015 a_dir = os.path.join(self.root_dir, u'ñoño'.encode('utf-8'))
@@ -2084,7 +2089,8 @@
2084 """FolderDeleted handler."""2089 """FolderDeleted handler."""
2085 self.assertRaises(KeyError, self.main.fs.get_by_path,2090 self.assertRaises(KeyError, self.main.fs.get_by_path,
2086 info['path'].decode('utf-8'))2091 info['path'].decode('utf-8'))
2087 self.assertRaises(KeyError, self.main.vm.get_volume, info['volume_id'])2092 self.assertRaises(VolumeDoesNotExist,
2093 self.main.vm.get_volume, info['volume_id'])
2088 d.callback(True)2094 d.callback(True)
2089 match = self.bus.add_signal_receiver(deleted_handler,2095 match = self.bus.add_signal_receiver(deleted_handler,
2090 signal_name='FolderDeleted')2096 signal_name='FolderDeleted')
@@ -2093,7 +2099,8 @@
2093 """the callback"""2099 """the callback"""
2094 self.assertNotIn(udf.volume_id, self.main.vm.udfs)2100 self.assertNotIn(udf.volume_id, self.main.vm.udfs)
2095 self.assertRaises(KeyError, self.main.fs.get_by_path, udf.path)2101 self.assertRaises(KeyError, self.main.fs.get_by_path, udf.path)
2096 self.assertRaises(KeyError, self.main.vm.get_volume, udf.volume_id)2102 self.assertRaises(VolumeDoesNotExist,
2103 self.main.vm.get_volume, udf.volume_id)
2097 self.folders_client.call_method('delete', udf.volume_id,2104 self.folders_client.call_method('delete', udf.volume_id,
2098 reply_handler=check_deleted,2105 reply_handler=check_deleted,
2099 error_handler=self.error_handler)2106 error_handler=self.error_handler)
@@ -2126,6 +2133,24 @@
2126 return d2133 return d
21272134
2128 @defer.inlineCallbacks2135 @defer.inlineCallbacks
2136 def test_delete_error_signal_folder_id(self):
2137 """Test for FolderDeleteError for a volume that doesn't exists."""
2138 udf_id = 'foobar'
2139 d = defer.Deferred()
2140 def deleted_error_handler(info, error):
2141 """FolderDeleteError handler"""
2142 d.callback((info, error))
2143 match = self.bus.add_signal_receiver(deleted_error_handler,
2144 signal_name='FolderDeleteError')
2145 self.signal_receivers.add(match)
2146 self.folders_client.call_method('delete', udf_id,
2147 reply_handler=lambda *args: None,
2148 error_handler=d.errback)
2149 info, error = yield d
2150 self.assertEquals(info['volume_id'], udf_id)
2151 self.assertEquals(error, "DOES_NOT_EXIST")
2152
2153 @defer.inlineCallbacks
2129 def test_subscribe(self):2154 def test_subscribe(self):
2130 """Test for Folders.subscribe and that it fires a dbus signal."""2155 """Test for Folders.subscribe and that it fires a dbus signal."""
2131 suggested_path = u'~/ñoño'2156 suggested_path = u'~/ñoño'
@@ -2230,7 +2255,8 @@
2230 """FolderDeleted handler."""2255 """FolderDeleted handler."""
2231 self.assertRaises(KeyError, self.main.fs.get_by_path,2256 self.assertRaises(KeyError, self.main.fs.get_by_path,
2232 info['path'].decode('utf-8'))2257 info['path'].decode('utf-8'))
2233 self.assertRaises(KeyError, self.main.vm.get_volume, info['volume_id'])2258 self.assertRaises(VolumeDoesNotExist,
2259 self.main.vm.get_volume, info['volume_id'])
2234 d.callback(True)2260 d.callback(True)
2235 match = self.bus.add_signal_receiver(deleted_handler,2261 match = self.bus.add_signal_receiver(deleted_handler,
2236 signal_name='ShareDeleted')2262 signal_name='ShareDeleted')
@@ -2239,7 +2265,8 @@
2239 """the callback"""2265 """the callback"""
2240 self.assertNotIn(share.volume_id, self.main.vm.shares)2266 self.assertNotIn(share.volume_id, self.main.vm.shares)
2241 self.assertRaises(KeyError, self.main.fs.get_by_path, share.path)2267 self.assertRaises(KeyError, self.main.fs.get_by_path, share.path)
2242 self.assertRaises(KeyError, self.main.vm.get_volume, share.volume_id)2268 self.assertRaises(VolumeDoesNotExist,
2269 self.main.vm.get_volume, share.volume_id)
2243 client = DBusClient(self.bus, '/shares', DBUS_IFACE_SHARES_NAME)2270 client = DBusClient(self.bus, '/shares', DBUS_IFACE_SHARES_NAME)
2244 client.call_method('delete_share', share.volume_id,2271 client.call_method('delete_share', share.volume_id,
2245 reply_handler=check_deleted,2272 reply_handler=check_deleted,
22462273
=== modified file 'tests/syncdaemon/test_vm.py'
--- tests/syncdaemon/test_vm.py 2010-05-20 14:52:09 +0000
+++ tests/syncdaemon/test_vm.py 2010-06-02 18:22:20 +0000
@@ -46,6 +46,7 @@
46 LegacyShareFileShelf,46 LegacyShareFileShelf,
47 MetadataUpgrader,47 MetadataUpgrader,
48 VMFileShelf,48 VMFileShelf,
49 VolumeDoesNotExist,
49)50)
50from twisted.internet import defer, reactor51from twisted.internet import defer, reactor
5152
@@ -1376,6 +1377,13 @@
1376 self.vm.delete_volume(udf.volume_id)1377 self.vm.delete_volume(udf.volume_id)
1377 yield d1378 yield d
13781379
1380 def test_handle_AQ_DELETE_VOLUME_ERROR_missing_volume(self):
1381 """Test for handle_AQ_DELETE_VOLUME_ERROR for a missing volume."""
1382 volume_id = 'foobar'
1383 self.assertRaises(VolumeDoesNotExist,
1384 self.vm.handle_AQ_DELETE_VOLUME_ERROR,
1385 volume_id=volume_id, error="ERROR!")
1386
1379 def _test_handle_SV_VOLUME_CREATED(self, auto_subscribe):1387 def _test_handle_SV_VOLUME_CREATED(self, auto_subscribe):
1380 """Test for handle_SV_VOLUME_CREATED."""1388 """Test for handle_SV_VOLUME_CREATED."""
1381 user_conf = config.get_user_config()1389 user_conf = config.get_user_config()
13821390
=== modified file 'ubuntuone/syncdaemon/dbus_interface.py'
--- ubuntuone/syncdaemon/dbus_interface.py 2010-05-19 19:57:54 +0000
+++ ubuntuone/syncdaemon/dbus_interface.py 2010-06-02 18:22:20 +0000
@@ -32,7 +32,7 @@
32from ubuntuone.syncdaemon.event_queue import EVENTS32from ubuntuone.syncdaemon.event_queue import EVENTS
33from ubuntuone.syncdaemon.interfaces import IMarker33from ubuntuone.syncdaemon.interfaces import IMarker
34from ubuntuone.syncdaemon import config34from ubuntuone.syncdaemon import config
35from ubuntuone.syncdaemon.volume_manager import Share, UDF35from ubuntuone.syncdaemon.volume_manager import Share, UDF, VolumeDoesNotExist
3636
3737
38# Disable the "Invalid Name" check here, as we have lots of DBus style names38# Disable the "Invalid Name" check here, as we have lots of DBus style names
@@ -278,7 +278,7 @@
278 signature='sa{ss}')278 signature='sa{ss}')
279 def DownloadFileProgress(self, path, info):279 def DownloadFileProgress(self, path, info):
280 """Fire a D-BUS signal, notifying about a download progress."""280 """Fire a D-BUS signal, notifying about a download progress."""
281 pass 281 pass
282282
283 @dbus.service.signal(DBUS_IFACE_STATUS_NAME,283 @dbus.service.signal(DBUS_IFACE_STATUS_NAME,
284 signature='sa{ss}')284 signature='sa{ss}')
@@ -295,7 +295,7 @@
295 signature='sa{ss}')295 signature='sa{ss}')
296 def UploadFileProgress(self, path, info):296 def UploadFileProgress(self, path, info):
297 """Fire a D-BUS signal, notifying about an upload progress."""297 """Fire a D-BUS signal, notifying about an upload progress."""
298 pass 298 pass
299299
300 @dbus.service.signal(DBUS_IFACE_STATUS_NAME,300 @dbus.service.signal(DBUS_IFACE_STATUS_NAME,
301 signature='sa{ss}')301 signature='sa{ss}')
@@ -502,7 +502,7 @@
502 n_bytes_read=n_bytes_read,502 n_bytes_read=n_bytes_read,
503 deflated_size=deflated_size503 deflated_size=deflated_size
504 )504 )
505 505
506 def handle_AQ_DOWNLOAD_FINISHED(self, share_id, node_id, server_hash):506 def handle_AQ_DOWNLOAD_FINISHED(self, share_id, node_id, server_hash):
507 """ handle AQ_DOWNLOAD_FINISHED """507 """ handle AQ_DOWNLOAD_FINISHED """
508 self.handle_default('AQ_DOWNLOAD_FINISHED', share_id,508 self.handle_default('AQ_DOWNLOAD_FINISHED', share_id,
@@ -586,7 +586,7 @@
586 n_bytes_written=n_bytes_written,586 n_bytes_written=n_bytes_written,
587 deflated_size=deflated_size587 deflated_size=deflated_size
588 )588 )
589 589
590 def handle_AQ_UPLOAD_FINISHED(self, share_id, node_id, hash):590 def handle_AQ_UPLOAD_FINISHED(self, share_id, node_id, hash):
591 """ handle AQ_UPLOAD_FINISHED """591 """ handle AQ_UPLOAD_FINISHED """
592 self.handle_default('AQ_UPLOAD_FINISHED', share_id, node_id, hash)592 self.handle_default('AQ_UPLOAD_FINISHED', share_id, node_id, hash)
@@ -737,9 +737,9 @@
737 self.handle_default('VM_VOLUME_DELETE_ERROR', volume_id, error)737 self.handle_default('VM_VOLUME_DELETE_ERROR', volume_id, error)
738 try:738 try:
739 volume = self.dbus_iface.volume_manager.get_volume(volume_id)739 volume = self.dbus_iface.volume_manager.get_volume(volume_id)
740 except KeyError:740 except VolumeDoesNotExist:
741 logger.error("Unable to handle VM_VOLUME_DELETE_ERROR for "741 logger.error("Unable to handle VM_VOLUME_DELETE_ERROR for "
742 "volume_id=%r", volume_id)742 "volume_id=%r, no such volume.", volume_id)
743 else:743 else:
744 if isinstance(volume, Share):744 if isinstance(volume, Share):
745 self.dbus_iface.shares.emit_share_delete_error(volume, error)745 self.dbus_iface.shares.emit_share_delete_error(volume, error)
@@ -954,9 +954,12 @@
954 try:954 try:
955 self.vm.delete_volume(str(share_id))955 self.vm.delete_volume(str(share_id))
956 reply_handler()956 reply_handler()
957 except KeyError:957 except VolumeDoesNotExist, e:
958 error_handler(ValueError("The volume with id: %s don't exists" % \958 self.ShareDeleteError({'volume_id':share_id}, str(e))
959 str(share_id)))959 except Exception, e:
960 error_handler(e)
961 logger.exception('Error while deleting share: %r', share_id)
962 self.ShareDeleteError({'volume_id':share_id}, str(e))
960963
961964
962 @dbus.service.signal(DBUS_IFACE_SHARES_NAME,965 @dbus.service.signal(DBUS_IFACE_SHARES_NAME,
@@ -1337,9 +1340,11 @@
1337 logger.debug('Folders.delete: %r', folder_id)1340 logger.debug('Folders.delete: %r', folder_id)
1338 try:1341 try:
1339 self.vm.delete_volume(folder_id)1342 self.vm.delete_volume(folder_id)
1343 except VolumeDoesNotExist, e:
1344 self.FolderDeleteError({'volume_id':folder_id}, str(e))
1340 except Exception, e:1345 except Exception, e:
1341 logger.exception('Error while deleting volume: %r', folder_id)1346 logger.exception('Error while deleting volume: %r', folder_id)
1342 self.emit_folder_delete_error({'id':folder_id}, str(e))1347 self.FolderDeleteError({'volume_id':folder_id}, str(e))
13431348
1344 @dbus.service.method(DBUS_IFACE_FOLDERS_NAME, out_signature='aa{ss}')1349 @dbus.service.method(DBUS_IFACE_FOLDERS_NAME, out_signature='aa{ss}')
1345 def get_folders(self):1350 def get_folders(self):
13461351
=== modified file 'ubuntuone/syncdaemon/filesystem_manager.py'
--- ubuntuone/syncdaemon/filesystem_manager.py 2010-03-26 20:24:15 +0000
+++ ubuntuone/syncdaemon/filesystem_manager.py 2010-06-02 18:22:20 +0000
@@ -29,6 +29,7 @@
29import stat29import stat
3030
31from ubuntuone.syncdaemon import file_shelf31from ubuntuone.syncdaemon import file_shelf
32from ubuntuone.syncdaemon.volume_manager import VolumeDoesNotExist
32import uuid33import uuid
3334
34METADATA_VERSION = "4"35METADATA_VERSION = "4"
@@ -277,7 +278,7 @@
277 # check if the share exists278 # check if the share exists
278 try:279 try:
279 self._get_share(mdobj["share_id"])280 self._get_share(mdobj["share_id"])
280 except KeyError:281 except VolumeDoesNotExist:
281 # oops, the share is gone!, invalidate this mdid282 # oops, the share is gone!, invalidate this mdid
282 log_warning('Share %r disappeared! deleting mdid: %s', mdobj['share_id'], mdid)283 log_warning('Share %r disappeared! deleting mdid: %s', mdobj['share_id'], mdid)
283 del self.fs[mdid]284 del self.fs[mdid]
284285
=== modified file 'ubuntuone/syncdaemon/volume_manager.py'
--- ubuntuone/syncdaemon/volume_manager.py 2010-05-21 14:30:25 +0000
+++ ubuntuone/syncdaemon/volume_manager.py 2010-06-02 18:22:20 +0000
@@ -276,6 +276,20 @@
276 return result276 return result
277277
278278
279class VolumeDoesNotExist(Exception):
280 """Exception for non existing volumes."""
281
282 msg = 'DOES_NOT_EXIST'
283
284 def __init__(self, volume_id):
285 """Create the instance."""
286 super(VolumeDoesNotExist, self).__init__(self.msg, volume_id)
287
288 def __str__(self):
289 """The error message."""
290 return self.msg
291
292
279class VolumeManager(object):293class VolumeManager(object):
280 """Manages shares and mount points."""294 """Manages shares and mount points."""
281295
@@ -807,13 +821,13 @@
807 del self.udfs[udf_id]821 del self.udfs[udf_id]
808 self.m.event_q.push('VM_VOLUME_DELETED', udf)822 self.m.event_q.push('VM_VOLUME_DELETED', udf)
809823
810 def get_volume(self, id):824 def get_volume(self, volume_id):
811 """Returns the Share or UDF with the matching id."""825 """Returns the Share or UDF with the matching id."""
812 volume = self.shares.get(id, None)826 volume = self.shares.get(volume_id, None)
813 if volume is None:827 if volume is None:
814 volume = self.udfs.get(id, None)828 volume = self.udfs.get(volume_id, None)
815 if volume is None:829 if volume is None:
816 raise KeyError(id)830 raise VolumeDoesNotExist(volume_id)
817 return volume831 return volume
818832
819 def get_volumes(self, all_volumes=False):833 def get_volumes(self, all_volumes=False):
@@ -920,13 +934,8 @@
920934
921 """935 """
922 self.log.info('delete_volume: %r', volume_id)936 self.log.info('delete_volume: %r', volume_id)
923 try:937 volume = self.get_volume(volume_id)
924 volume = self.get_volume(volume_id)938 self.m.action_q.delete_volume(volume.id)
925 except KeyError:
926 self.m.event_q.push('VM_VOLUME_DELETE_ERROR', volume_id,
927 "DOES_NOT_EXIST")
928 else:
929 self.m.action_q.delete_volume(volume.id)
930939
931 def subscribe_udf(self, udf_id):940 def subscribe_udf(self, udf_id):
932 """Mark the UDF with id as subscribed.941 """Mark the UDF with id as subscribed.

Subscribers

People subscribed via source and target branches