Merge lp:~nataliabidart/ubuntuone-control-panel/wait-for-it into lp:ubuntuone-control-panel

Proposed by Natalia Bidart on 2012-03-29
Status: Merged
Approved by: Natalia Bidart on 2012-03-29
Approved revision: 304
Merged at revision: 305
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/wait-for-it
Merge into: lp:ubuntuone-control-panel
Diff against target: 455 lines (+54/-194)
8 files modified
ubuntuone/controlpanel/backend.py (+4/-1)
ubuntuone/controlpanel/dbustests/test_sd_client/test_linux.py (+0/-94)
ubuntuone/controlpanel/gui/qt/folders.py (+2/-1)
ubuntuone/controlpanel/gui/qt/tests/test_folders.py (+2/-1)
ubuntuone/controlpanel/sd_client/__init__.py (+6/-13)
ubuntuone/controlpanel/sd_client/linux.py (+0/-46)
ubuntuone/controlpanel/tests/test_backend.py (+34/-21)
ubuntuone/controlpanel/tests/test_sd_client.py (+6/-17)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/wait-for-it
Reviewer Review Type Date Requested Status
Brian Curtin (community) Approve on 2012-03-29
Roberto Alsina (community) 2012-03-29 Approve on 2012-03-29
Review via email: mp+99983@code.launchpad.net

Commit Message

- Make use of the new feature from syncdaemon where 'refresh_volumes'
  returns a deferred that gets fired when the server info is ready
  (LP: #851810).

To post a comment you must log in.
303. By Natalia Bidart on 2012-03-29

Merged trunk in.

Roberto Alsina (ralsina) wrote :

+1

review: Approve
304. By Natalia Bidart on 2012-03-29

- No longer need to skip the status changed handler setting.

Brian Curtin (brian.curtin) wrote :

Approved. Tests pass on Windows

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntuone/controlpanel/backend.py'
2--- ubuntuone/controlpanel/backend.py 2012-03-28 12:06:28 +0000
3+++ ubuntuone/controlpanel/backend.py 2012-03-29 18:32:21 +0000
4@@ -599,7 +599,7 @@
5
6 @log_call(logger.debug)
7 @inlineCallbacks
8- def volumes_info(self, with_storage_info=True):
9+ def volumes_info(self, with_storage_info=True, refresh=False):
10 """Get the volumes info."""
11 self._volumes = {}
12
13@@ -612,6 +612,9 @@
14 else:
15 free_bytes = account['quota_total'] - account['quota_used']
16
17+ if refresh:
18+ yield self.sd_client.refresh_volumes()
19+
20 root_dir = yield self.sd_client.get_root_dir()
21 shares_dir = yield self.sd_client.get_shares_dir()
22 shares_dir_link = yield self.sd_client.get_shares_dir_link()
23
24=== removed file 'ubuntuone/controlpanel/dbustests/test_sd_client/test_linux.py'
25--- ubuntuone/controlpanel/dbustests/test_sd_client/test_linux.py 2011-10-24 21:48:27 +0000
26+++ ubuntuone/controlpanel/dbustests/test_sd_client/test_linux.py 1970-01-01 00:00:00 +0000
27@@ -1,94 +0,0 @@
28-# -*- coding: utf-8 -*-
29-
30-# Authors: Alejandro J. Cura <alecu@canonical.com>
31-# Authors: Natalia B. Bidart <natalia.bidart@canonical.com>
32-#
33-# Copyright 2010 Canonical Ltd.
34-#
35-# This program is free software: you can redistribute it and/or modify it
36-# under the terms of the GNU General Public License version 3, as published
37-# by the Free Software Foundation.
38-#
39-# This program is distributed in the hope that it will be useful, but
40-# WITHOUT ANY WARRANTY; without even the implied warranties of
41-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
42-# PURPOSE. See the GNU General Public License for more details.
43-#
44-# You should have received a copy of the GNU General Public License along
45-# with this program. If not, see <http://www.gnu.org/licenses/>.
46-
47-"""Tests for the DBus service when accessing SyncDaemon."""
48-
49-import dbus
50-
51-from twisted.internet import defer
52-
53-from ubuntuone.platform.linux import dbus_interface as sd_dbus_iface
54-
55-from ubuntuone.controlpanel import sd_client
56-from ubuntuone.controlpanel.dbustests import DBusClientTestCase
57-
58-
59-SD_DBUS_IFACE_NAME = sd_dbus_iface.DBUS_IFACE_NAME
60-SD_DBUS_IFACE_STATUS_NAME = sd_dbus_iface.DBUS_IFACE_STATUS_NAME
61-
62-# pylint, you have to go to decorator's school
63-# pylint: disable=C0322
64-
65-# Access to a protected member of a client class
66-# pylint: disable=W0212
67-
68-
69-class StatusMockDBusSyncDaemon(dbus.service.Object):
70- """A mock object that mimicks syncdaemon regarding the Status iface."""
71-
72- state_dict = {
73- 'name': 'TEST',
74- 'description': 'Some test state, nothing else.',
75- 'is_error': '',
76- 'is_connected': 'True',
77- 'is_online': '',
78- 'queues': 'GORGEOUS',
79- 'connection': '',
80- }
81-
82- def _get_current_state(self):
83- """Get the current status of the system."""
84- return self.state_dict
85-
86- @dbus.service.method(SD_DBUS_IFACE_STATUS_NAME,
87- in_signature='', out_signature='a{ss}')
88- def current_status(self):
89- """Return the current faked status of the system."""
90- return self._get_current_state()
91-
92- # pylint: disable=C0103
93- # Invalid name "StatusChanged"
94-
95- @dbus.service.signal(SD_DBUS_IFACE_STATUS_NAME)
96- def StatusChanged(self, status):
97- """Fire a signal to notify that the status of the system changed."""
98-
99- def emit_status_changed(self, state=None):
100- """Emit StatusChanged."""
101- self.StatusChanged(self._get_current_state())
102-
103-
104-class StatusTestCase(DBusClientTestCase):
105- """Test for the status dbus client methods."""
106-
107- @defer.inlineCallbacks
108- def setUp(self):
109- yield super(StatusTestCase, self).setUp()
110- self.register_mockserver(SD_DBUS_IFACE_NAME,
111- "/status", StatusMockDBusSyncDaemon)
112-
113- def test_set_status_changed_handler(self):
114- """A proper callback can be connected to StatusChanged signal."""
115- client = sd_client.SyncDaemonClient()
116- _, sig = client.set_status_changed_handler(self._set_called)
117-
118- self.assertEqual(sig._handler, self._set_called)
119- self.assertEqual(sig._member, 'StatusChanged')
120- self.assertEqual(sig._path, '/status')
121- self.assertEqual(sig._interface, SD_DBUS_IFACE_STATUS_NAME)
122
123=== modified file 'ubuntuone/controlpanel/gui/qt/folders.py'
124--- ubuntuone/controlpanel/gui/qt/folders.py 2012-03-29 14:52:59 +0000
125+++ ubuntuone/controlpanel/gui/qt/folders.py 2012-03-29 18:32:21 +0000
126@@ -153,7 +153,8 @@
127 def load(self):
128 """Load specific tab info."""
129 self.is_processing = True
130- info = yield self.backend.volumes_info(with_storage_info=False)
131+ info = yield self.backend.volumes_info(with_storage_info=False,
132+ refresh=self.remote_folders)
133 self.process_info(info)
134
135 @handle_errors(logger=logger)
136
137=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
138--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-29 15:25:48 +0000
139+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-29 18:32:21 +0000
140@@ -187,7 +187,8 @@
141
142 def test_info_is_requested_on_load(self):
143 """The volumes info is requested to the backend."""
144- self.assert_backend_called('volumes_info', with_storage_info=False)
145+ self.assert_backend_called('volumes_info', with_storage_info=False,
146+ refresh=self.ui.remote_folders)
147
148 def test_process_info(self):
149 """The volumes info is processed when ready."""
150
151=== modified file 'ubuntuone/controlpanel/sd_client/__init__.py'
152--- ubuntuone/controlpanel/sd_client/__init__.py 2012-01-18 14:06:35 +0000
153+++ ubuntuone/controlpanel/sd_client/__init__.py 2012-03-29 18:32:21 +0000
154@@ -1,8 +1,6 @@
155 # -*- coding: utf-8 -*-
156-
157-# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
158 #
159-# Copyright 2011 Canonical Ltd.
160+# Copyright 2012 Canonical Ltd.
161 #
162 # This program is free software: you can redistribute it and/or modify it
163 # under the terms of the GNU General Public License version 3, as published
164@@ -18,7 +16,6 @@
165
166 """The syncdaemon client."""
167
168-import sys
169 import warnings
170
171 # pylint: disable=E0611
172@@ -35,7 +32,6 @@
173
174 def __init__(self):
175 """Get a proxy for the SyncDaemonTool."""
176- self.status_changed_handler = None
177 self.proxy = tools.SyncDaemonTool()
178
179 def get_throttling_limits(self):
180@@ -200,11 +196,8 @@
181
182 def set_status_changed_handler(self, handler):
183 """Set the status handler function."""
184- self.status_changed_handler = handler
185- if sys.platform.startswith("linux"):
186- # pylint: disable=W0404
187- from ubuntuone.controlpanel.sd_client import linux
188- result = linux.set_status_changed_handler(handler)
189- else:
190- result = self.proxy.set_status_changed_handler(handler)
191- return result
192+ return self.proxy.connect_signal('StatusChanged', handler)
193+
194+ def refresh_volumes(self):
195+ """Refresh the volumes information from syncdaemon."""
196+ return self.proxy.refresh_volumes()
197
198=== removed file 'ubuntuone/controlpanel/sd_client/linux.py'
199--- ubuntuone/controlpanel/sd_client/linux.py 2011-06-29 17:59:07 +0000
200+++ ubuntuone/controlpanel/sd_client/linux.py 1970-01-01 00:00:00 +0000
201@@ -1,46 +0,0 @@
202-# -*- coding: utf-8 -*-
203-
204-# Authors: Alejandro J. Cura <alecu@canonical.com>
205-# Authors: Natalia B. Bidart <nataliabidart@canonical.com>
206-#
207-# Copyright 2010 Canonical Ltd.
208-#
209-# This program is free software: you can redistribute it and/or modify it
210-# under the terms of the GNU General Public License version 3, as published
211-# by the Free Software Foundation.
212-#
213-# This program is distributed in the hope that it will be useful, but
214-# WITHOUT ANY WARRANTY; without even the implied warranties of
215-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
216-# PURPOSE. See the GNU General Public License for more details.
217-#
218-# You should have received a copy of the GNU General Public License along
219-# with this program. If not, see <http://www.gnu.org/licenses/>.
220-
221-"""Client to use other DBus services."""
222-
223-import dbus.service
224-
225-from ubuntuone.controlpanel.logger import setup_logging
226-
227-
228-logger = setup_logging('sd_client')
229-
230-
231-def get_syncdaemon_proxy(object_path, dbus_interface):
232- """Get a DBus proxy for syncdaemon at 'object_path':'dbus_interface'."""
233- logger.debug('get_syncdaemon_proxy: object_path %r, dbus_interface %r',
234- object_path, dbus_interface)
235- bus = dbus.SessionBus()
236- obj = bus.get_object(bus_name='com.ubuntuone.SyncDaemon',
237- object_path=object_path,
238- follow_name_owner_changes=True)
239- proxy = dbus.Interface(object=obj, dbus_interface=dbus_interface)
240- return proxy
241-
242-
243-def set_status_changed_handler(handler):
244- """Connect 'handler' with syncdaemon's StatusChanged signal."""
245- proxy = get_syncdaemon_proxy('/status', 'com.ubuntuone.SyncDaemon.Status')
246- sig = proxy.connect_to_signal('StatusChanged', handler)
247- return proxy, sig
248
249=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
250--- ubuntuone/controlpanel/tests/test_backend.py 2012-03-28 17:09:58 +0000
251+++ ubuntuone/controlpanel/tests/test_backend.py 2012-03-29 18:32:21 +0000
252@@ -169,6 +169,7 @@
253 self.actions = []
254 self.shares = []
255 self.folders = []
256+ self.volumes_refreshed = False
257
258 def get_throttling_limits(self):
259 """Return the sample speed limits."""
260@@ -319,6 +320,11 @@
261 """Grab list of shared (shares from the user to others)."""
262 return SAMPLE_SHARED
263
264+ def refresh_volumes(self):
265+ """Refresh the volume list."""
266+ self.volumes_refreshed = True
267+ return defer.succeed(None)
268+
269
270 class MockReplicationClient(CallRecorder):
271 """A mock replication_client module."""
272@@ -860,10 +866,19 @@
273 u'display_name': display_name,
274 }
275
276+ self.patch(self.be.sd_client, 'shares', SAMPLE_SHARES)
277+ self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
278+
279 @inlineCallbacks
280- def expected_volumes(self, sample_shares, sample_folders,
281+ def expected_volumes(self, sample_shares=None, sample_folders=None,
282 with_storage_info=True):
283 """Get shares and group by sharing user, get folders and free space."""
284+ if sample_shares is None:
285+ sample_shares = self.be.sd_client.shares
286+
287+ if sample_folders is None:
288+ sample_folders = self.be.sd_client.folders
289+
290 free_bytes = self.be.FREE_BYTES_NOT_AVAILABLE
291 if with_storage_info:
292 try:
293@@ -926,11 +941,19 @@
294 @inlineCallbacks
295 def test_volumes_info(self):
296 """The volumes_info method exercises its callback."""
297- self.patch(self.be.sd_client, 'shares', SAMPLE_SHARES)
298- self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
299-
300- expected = yield self.expected_volumes(SAMPLE_SHARES, SAMPLE_FOLDERS)
301+ expected = yield self.expected_volumes()
302 result = yield self.be.volumes_info()
303+
304+ self.assertEqual(result, expected)
305+ self.assertFalse(self.be.sd_client.volumes_refreshed)
306+
307+ @inlineCallbacks
308+ def test_volumes_info_can_refresh_volumes(self):
309+ """The volumes_info can be refreshed."""
310+ expected = yield self.expected_volumes()
311+ result = yield self.be.volumes_info(refresh=True)
312+
313+ self.assertTrue(self.be.sd_client.volumes_refreshed)
314 self.assertEqual(result, expected)
315
316 @inlineCallbacks
317@@ -943,7 +966,6 @@
318 path = path[len(USER_HOME) + 1:]
319 item[u'path'] = os.path.join(root_path, path)
320 self.patch(self.be.sd_client, 'shares', SAMPLE_SHARES)
321- self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
322
323 yield self.be.volumes_info()
324 for item in SAMPLE_FOLDERS:
325@@ -956,11 +978,7 @@
326 @inlineCallbacks
327 def test_volumes_info_without_storage_info(self):
328 """The volumes_info method exercises its callback."""
329- self.patch(self.be.sd_client, 'shares', SAMPLE_SHARES)
330- self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
331-
332- expected = yield self.expected_volumes(SAMPLE_SHARES, SAMPLE_FOLDERS,
333- with_storage_info=False)
334+ expected = yield self.expected_volumes(with_storage_info=False)
335 result = yield self.be.volumes_info(with_storage_info=False)
336 self.assertEqual(result, expected)
337
338@@ -971,11 +989,8 @@
339 @inlineCallbacks
340 def test_volumes_are_cached(self):
341 """The volume list is cached."""
342- self.patch(self.be.sd_client, 'shares', SAMPLE_SHARES)
343- self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
344-
345 expected = {}
346- info = yield self.expected_volumes(SAMPLE_SHARES, SAMPLE_FOLDERS)
347+ info = yield self.expected_volumes()
348 for _, _, data in info:
349 for volume in data:
350 sid = volume['volume_id']
351@@ -1024,10 +1039,8 @@
352 ]
353
354 self.patch(self.be.sd_client, 'shares', read_only_shares)
355- self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
356
357- expected = yield self.expected_volumes(read_only_shares,
358- SAMPLE_FOLDERS)
359+ expected = yield self.expected_volumes()
360 result = yield self.be.volumes_info()
361 self.assertEqual(result, expected)
362
363@@ -1035,10 +1048,8 @@
364 def test_volumes_info_no_quota_for_root(self):
365 """The volumes_info returns info even if quota call fails."""
366 self.be.wc.failure = 500
367- self.patch(self.be.sd_client, 'shares', SAMPLE_SHARES)
368- self.patch(self.be.sd_client, 'folders', SAMPLE_FOLDERS)
369
370- expected = yield self.expected_volumes(SAMPLE_SHARES, SAMPLE_FOLDERS)
371+ expected = yield self.expected_volumes()
372 result = yield self.be.volumes_info()
373
374 self.assertEqual(len(result), len(expected))
375@@ -1126,6 +1137,8 @@
376 @inlineCallbacks
377 def test_create_folder(self):
378 """New folders can be created."""
379+ self.patch(self.be.sd_client, 'folders', [])
380+
381 folder_path = os.path.join(USER_HOME, 'Test Me')
382 yield self.be.create_folder(folder_path=folder_path)
383
384
385=== modified file 'ubuntuone/controlpanel/tests/test_sd_client.py'
386--- ubuntuone/controlpanel/tests/test_sd_client.py 2012-03-19 17:16:43 +0000
387+++ ubuntuone/controlpanel/tests/test_sd_client.py 2012-03-29 18:32:21 +0000
388@@ -1,9 +1,6 @@
389 # -*- coding: utf-8 -*-
390-
391-# Authors: Alejandro J. Cura <alecu@canonical.com>
392-# Authors: Natalia B. Bidart <natalia.bidart@canonical.com>
393 #
394-# Copyright 2010 Canonical Ltd.
395+# Copyright 2010-2012 Canonical Ltd.
396 #
397 # This program is free software: you can redistribute it and/or modify it
398 # under the terms of the GNU General Public License version 3, as published
399@@ -24,11 +21,7 @@
400
401 from twisted.internet import defer
402 from twisted.internet.defer import inlineCallbacks, returnValue
403-from ubuntuone.devtools.testcases import skipIfNotOS
404-# No name 'tools' in module 'ubuntuone.platform'
405-# pylint: disable=E0611
406 from ubuntuone.platform import tools
407-# pylint: enable=E0611
408 from ubuntuone.syncdaemon.interaction_interfaces import bool_str
409
410 from ubuntuone.controlpanel import sd_client
411@@ -183,14 +176,12 @@
412 @inlineCallbacks
413 def subscribe_folder(self, folder_id):
414 """Subscribe to a user defined folder given its id."""
415- yield self._set_folder_attr(folder_id,
416- u'subscribed', True)
417+ yield self._set_folder_attr(folder_id, u'subscribed', True)
418
419 @inlineCallbacks
420 def unsubscribe_folder(self, folder_id):
421 """Unsubscribe from a user defined folder given its id."""
422- yield self._set_folder_attr(folder_id,
423- u'subscribed', False)
424+ yield self._set_folder_attr(folder_id, u'subscribed', False)
425
426 @inlineCallbacks
427 def get_folders(self):
428@@ -315,9 +306,9 @@
429 """Return the shares link directory."""
430 return self.shares_dir_link
431
432- def set_status_changed_handler(self, handler):
433+ def connect_signal(self, signal_name, handler):
434 """Set the handler for the status changed signal."""
435- self.called['status_changed_handler'] = handler
436+ self.called[signal_name] = handler
437
438
439 class BaseTestCase(TestCase):
440@@ -694,14 +685,12 @@
441
442 self.assertEqual(self.sd.proxy.called['quit'], None)
443
444- @skipIfNotOS('win32', 'The tested function is only defined on windows')
445 @inlineCallbacks
446 def test_set_status_changed_handler(self):
447 """Connect a handler to the status changed signal."""
448 sample_handler = object()
449 yield self.sd.set_status_changed_handler(sample_handler)
450- self.assertEqual(sample_handler,
451- self.sd.proxy.called['status_changed_handler'])
452+ self.assertEqual(sample_handler, self.sd.proxy.called['StatusChanged'])
453
454
455 class BasicTestCase(BaseTestCase):

Subscribers

People subscribed via source and target branches