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
1=== modified file 'tests/syncdaemon/test_dbus.py'
2--- tests/syncdaemon/test_dbus.py 2010-05-19 19:57:54 +0000
3+++ tests/syncdaemon/test_dbus.py 2010-06-02 18:22:20 +0000
4@@ -37,7 +37,12 @@
5 DBUS_IFACE_PUBLIC_FILES_NAME,
6 EventListener,
7 )
8-from ubuntuone.syncdaemon.volume_manager import Share, Shared, UDF
9+from ubuntuone.syncdaemon.volume_manager import (
10+ Share,
11+ Shared,
12+ UDF,
13+ VolumeDoesNotExist,
14+)
15 from ubuntuone.syncdaemon.tools import DBusClient
16 from ubuntuone.syncdaemon import event_queue, states, main, config
17 from contrib.testing.testcase import (
18@@ -1004,7 +1009,7 @@
19 n_bytes_read=10,
20 deflated_size=20)
21 return d
22-
23+
24 def test_download_finished(self):
25 """ Test the DBus signals in Status """
26 a_dir = os.path.join(self.root_dir, u'ñoño'.encode('utf-8'))
27@@ -2084,7 +2089,8 @@
28 """FolderDeleted handler."""
29 self.assertRaises(KeyError, self.main.fs.get_by_path,
30 info['path'].decode('utf-8'))
31- self.assertRaises(KeyError, self.main.vm.get_volume, info['volume_id'])
32+ self.assertRaises(VolumeDoesNotExist,
33+ self.main.vm.get_volume, info['volume_id'])
34 d.callback(True)
35 match = self.bus.add_signal_receiver(deleted_handler,
36 signal_name='FolderDeleted')
37@@ -2093,7 +2099,8 @@
38 """the callback"""
39 self.assertNotIn(udf.volume_id, self.main.vm.udfs)
40 self.assertRaises(KeyError, self.main.fs.get_by_path, udf.path)
41- self.assertRaises(KeyError, self.main.vm.get_volume, udf.volume_id)
42+ self.assertRaises(VolumeDoesNotExist,
43+ self.main.vm.get_volume, udf.volume_id)
44 self.folders_client.call_method('delete', udf.volume_id,
45 reply_handler=check_deleted,
46 error_handler=self.error_handler)
47@@ -2126,6 +2133,24 @@
48 return d
49
50 @defer.inlineCallbacks
51+ def test_delete_error_signal_folder_id(self):
52+ """Test for FolderDeleteError for a volume that doesn't exists."""
53+ udf_id = 'foobar'
54+ d = defer.Deferred()
55+ def deleted_error_handler(info, error):
56+ """FolderDeleteError handler"""
57+ d.callback((info, error))
58+ match = self.bus.add_signal_receiver(deleted_error_handler,
59+ signal_name='FolderDeleteError')
60+ self.signal_receivers.add(match)
61+ self.folders_client.call_method('delete', udf_id,
62+ reply_handler=lambda *args: None,
63+ error_handler=d.errback)
64+ info, error = yield d
65+ self.assertEquals(info['volume_id'], udf_id)
66+ self.assertEquals(error, "DOES_NOT_EXIST")
67+
68+ @defer.inlineCallbacks
69 def test_subscribe(self):
70 """Test for Folders.subscribe and that it fires a dbus signal."""
71 suggested_path = u'~/ñoño'
72@@ -2230,7 +2255,8 @@
73 """FolderDeleted handler."""
74 self.assertRaises(KeyError, self.main.fs.get_by_path,
75 info['path'].decode('utf-8'))
76- self.assertRaises(KeyError, self.main.vm.get_volume, info['volume_id'])
77+ self.assertRaises(VolumeDoesNotExist,
78+ self.main.vm.get_volume, info['volume_id'])
79 d.callback(True)
80 match = self.bus.add_signal_receiver(deleted_handler,
81 signal_name='ShareDeleted')
82@@ -2239,7 +2265,8 @@
83 """the callback"""
84 self.assertNotIn(share.volume_id, self.main.vm.shares)
85 self.assertRaises(KeyError, self.main.fs.get_by_path, share.path)
86- self.assertRaises(KeyError, self.main.vm.get_volume, share.volume_id)
87+ self.assertRaises(VolumeDoesNotExist,
88+ self.main.vm.get_volume, share.volume_id)
89 client = DBusClient(self.bus, '/shares', DBUS_IFACE_SHARES_NAME)
90 client.call_method('delete_share', share.volume_id,
91 reply_handler=check_deleted,
92
93=== modified file 'tests/syncdaemon/test_vm.py'
94--- tests/syncdaemon/test_vm.py 2010-05-20 14:52:09 +0000
95+++ tests/syncdaemon/test_vm.py 2010-06-02 18:22:20 +0000
96@@ -46,6 +46,7 @@
97 LegacyShareFileShelf,
98 MetadataUpgrader,
99 VMFileShelf,
100+ VolumeDoesNotExist,
101 )
102 from twisted.internet import defer, reactor
103
104@@ -1376,6 +1377,13 @@
105 self.vm.delete_volume(udf.volume_id)
106 yield d
107
108+ def test_handle_AQ_DELETE_VOLUME_ERROR_missing_volume(self):
109+ """Test for handle_AQ_DELETE_VOLUME_ERROR for a missing volume."""
110+ volume_id = 'foobar'
111+ self.assertRaises(VolumeDoesNotExist,
112+ self.vm.handle_AQ_DELETE_VOLUME_ERROR,
113+ volume_id=volume_id, error="ERROR!")
114+
115 def _test_handle_SV_VOLUME_CREATED(self, auto_subscribe):
116 """Test for handle_SV_VOLUME_CREATED."""
117 user_conf = config.get_user_config()
118
119=== modified file 'ubuntuone/syncdaemon/dbus_interface.py'
120--- ubuntuone/syncdaemon/dbus_interface.py 2010-05-19 19:57:54 +0000
121+++ ubuntuone/syncdaemon/dbus_interface.py 2010-06-02 18:22:20 +0000
122@@ -32,7 +32,7 @@
123 from ubuntuone.syncdaemon.event_queue import EVENTS
124 from ubuntuone.syncdaemon.interfaces import IMarker
125 from ubuntuone.syncdaemon import config
126-from ubuntuone.syncdaemon.volume_manager import Share, UDF
127+from ubuntuone.syncdaemon.volume_manager import Share, UDF, VolumeDoesNotExist
128
129
130 # Disable the "Invalid Name" check here, as we have lots of DBus style names
131@@ -278,7 +278,7 @@
132 signature='sa{ss}')
133 def DownloadFileProgress(self, path, info):
134 """Fire a D-BUS signal, notifying about a download progress."""
135- pass
136+ pass
137
138 @dbus.service.signal(DBUS_IFACE_STATUS_NAME,
139 signature='sa{ss}')
140@@ -295,7 +295,7 @@
141 signature='sa{ss}')
142 def UploadFileProgress(self, path, info):
143 """Fire a D-BUS signal, notifying about an upload progress."""
144- pass
145+ pass
146
147 @dbus.service.signal(DBUS_IFACE_STATUS_NAME,
148 signature='sa{ss}')
149@@ -502,7 +502,7 @@
150 n_bytes_read=n_bytes_read,
151 deflated_size=deflated_size
152 )
153-
154+
155 def handle_AQ_DOWNLOAD_FINISHED(self, share_id, node_id, server_hash):
156 """ handle AQ_DOWNLOAD_FINISHED """
157 self.handle_default('AQ_DOWNLOAD_FINISHED', share_id,
158@@ -586,7 +586,7 @@
159 n_bytes_written=n_bytes_written,
160 deflated_size=deflated_size
161 )
162-
163+
164 def handle_AQ_UPLOAD_FINISHED(self, share_id, node_id, hash):
165 """ handle AQ_UPLOAD_FINISHED """
166 self.handle_default('AQ_UPLOAD_FINISHED', share_id, node_id, hash)
167@@ -737,9 +737,9 @@
168 self.handle_default('VM_VOLUME_DELETE_ERROR', volume_id, error)
169 try:
170 volume = self.dbus_iface.volume_manager.get_volume(volume_id)
171- except KeyError:
172+ except VolumeDoesNotExist:
173 logger.error("Unable to handle VM_VOLUME_DELETE_ERROR for "
174- "volume_id=%r", volume_id)
175+ "volume_id=%r, no such volume.", volume_id)
176 else:
177 if isinstance(volume, Share):
178 self.dbus_iface.shares.emit_share_delete_error(volume, error)
179@@ -954,9 +954,12 @@
180 try:
181 self.vm.delete_volume(str(share_id))
182 reply_handler()
183- except KeyError:
184- error_handler(ValueError("The volume with id: %s don't exists" % \
185- str(share_id)))
186+ except VolumeDoesNotExist, e:
187+ self.ShareDeleteError({'volume_id':share_id}, str(e))
188+ except Exception, e:
189+ error_handler(e)
190+ logger.exception('Error while deleting share: %r', share_id)
191+ self.ShareDeleteError({'volume_id':share_id}, str(e))
192
193
194 @dbus.service.signal(DBUS_IFACE_SHARES_NAME,
195@@ -1337,9 +1340,11 @@
196 logger.debug('Folders.delete: %r', folder_id)
197 try:
198 self.vm.delete_volume(folder_id)
199+ except VolumeDoesNotExist, e:
200+ self.FolderDeleteError({'volume_id':folder_id}, str(e))
201 except Exception, e:
202 logger.exception('Error while deleting volume: %r', folder_id)
203- self.emit_folder_delete_error({'id':folder_id}, str(e))
204+ self.FolderDeleteError({'volume_id':folder_id}, str(e))
205
206 @dbus.service.method(DBUS_IFACE_FOLDERS_NAME, out_signature='aa{ss}')
207 def get_folders(self):
208
209=== modified file 'ubuntuone/syncdaemon/filesystem_manager.py'
210--- ubuntuone/syncdaemon/filesystem_manager.py 2010-03-26 20:24:15 +0000
211+++ ubuntuone/syncdaemon/filesystem_manager.py 2010-06-02 18:22:20 +0000
212@@ -29,6 +29,7 @@
213 import stat
214
215 from ubuntuone.syncdaemon import file_shelf
216+from ubuntuone.syncdaemon.volume_manager import VolumeDoesNotExist
217 import uuid
218
219 METADATA_VERSION = "4"
220@@ -277,7 +278,7 @@
221 # check if the share exists
222 try:
223 self._get_share(mdobj["share_id"])
224- except KeyError:
225+ except VolumeDoesNotExist:
226 # oops, the share is gone!, invalidate this mdid
227 log_warning('Share %r disappeared! deleting mdid: %s', mdobj['share_id'], mdid)
228 del self.fs[mdid]
229
230=== modified file 'ubuntuone/syncdaemon/volume_manager.py'
231--- ubuntuone/syncdaemon/volume_manager.py 2010-05-21 14:30:25 +0000
232+++ ubuntuone/syncdaemon/volume_manager.py 2010-06-02 18:22:20 +0000
233@@ -276,6 +276,20 @@
234 return result
235
236
237+class VolumeDoesNotExist(Exception):
238+ """Exception for non existing volumes."""
239+
240+ msg = 'DOES_NOT_EXIST'
241+
242+ def __init__(self, volume_id):
243+ """Create the instance."""
244+ super(VolumeDoesNotExist, self).__init__(self.msg, volume_id)
245+
246+ def __str__(self):
247+ """The error message."""
248+ return self.msg
249+
250+
251 class VolumeManager(object):
252 """Manages shares and mount points."""
253
254@@ -807,13 +821,13 @@
255 del self.udfs[udf_id]
256 self.m.event_q.push('VM_VOLUME_DELETED', udf)
257
258- def get_volume(self, id):
259+ def get_volume(self, volume_id):
260 """Returns the Share or UDF with the matching id."""
261- volume = self.shares.get(id, None)
262- if volume is None:
263- volume = self.udfs.get(id, None)
264- if volume is None:
265- raise KeyError(id)
266+ volume = self.shares.get(volume_id, None)
267+ if volume is None:
268+ volume = self.udfs.get(volume_id, None)
269+ if volume is None:
270+ raise VolumeDoesNotExist(volume_id)
271 return volume
272
273 def get_volumes(self, all_volumes=False):
274@@ -920,13 +934,8 @@
275
276 """
277 self.log.info('delete_volume: %r', volume_id)
278- try:
279- volume = self.get_volume(volume_id)
280- except KeyError:
281- self.m.event_q.push('VM_VOLUME_DELETE_ERROR', volume_id,
282- "DOES_NOT_EXIST")
283- else:
284- self.m.action_q.delete_volume(volume.id)
285+ volume = self.get_volume(volume_id)
286+ self.m.action_q.delete_volume(volume.id)
287
288 def subscribe_udf(self, udf_id):
289 """Mark the UDF with id as subscribed.

Subscribers

People subscribed via source and target branches