Merge lp:~chipaca/ubuntuone-client/branch-of-glowing-plus-three-hateage into lp:ubuntuone-client

Proposed by John Lenton
Status: Merged
Approved by: dobey
Approved revision: 501
Merged at revision: not available
Proposed branch: lp:~chipaca/ubuntuone-client/branch-of-glowing-plus-three-hateage
Merge into: lp:ubuntuone-client
Diff against target: 454 lines (+120/-63)
3 files modified
bin/ubuntuone-preferences (+56/-40)
tests/test_preferences.py (+46/-8)
ubuntuone/syncdaemon/tools.py (+18/-15)
To merge this branch: bzr merge lp:~chipaca/ubuntuone-client/branch-of-glowing-plus-three-hateage
Reviewer Review Type Date Requested Status
Rick McBride (community) Approve
dobey (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+23428@code.launchpad.net

Commit message

This fixes several long-standing bugs in ubuntuone-preferences.

Description of the change

This fixes several long-standing bugs in ubuntuone-preferences.

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Tests pass, syncdaemon and u1prefs work.

review: Approve
Revision history for this message
dobey (dobey) :
review: Approve
Revision history for this message
Rick McBride (rmcbride) wrote :

nice

review: Approve
Revision history for this message
dobey (dobey) wrote :
Download full text (33.2 KiB)

The attempt to merge lp:~chipaca/ubuntuone-client/branch-of-glowing-plus-three-hateage into lp:ubuntuone-client failed.Below is the output from the failed tests.

/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
(B testing autoconf2.50... not found.
  testing autoconf... found 2.65
checking for automake >= 1.10...
(B testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
(B testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
(B testing intltoolize... found 0.41.0
checking for pkg-config >= 0.14.0...
(B testing pkg-config... found 0.22
Checking for required M4 macros...
(BChecking for forbidden M4 macros...
(BProcessing ./configure.ac
(BRunning libtoolize...
(Blibtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
(BRunning aclocal-1.11...
(BRunning autoconf...
(BRunning autoheader...
(BRunning automake-1.11...
(BRunning ./configure --prefix=/usr ...
(Bchecking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checki...

501. By John Lenton

twisted defer lint

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/ubuntuone-preferences'
2--- bin/ubuntuone-preferences 2010-04-09 15:09:21 +0000
3+++ bin/ubuntuone-preferences 2010-04-14 23:56:26 +0000
4@@ -220,21 +220,10 @@
5 """
6 Push the bandwidth settings at syncdaemon.
7 """
8- try:
9- client = self.bus.get_object(DBUS_IFACE_NAME, "/config",
10- follow_name_owner_changes=True)
11- iface = dbus.Interface(client, DBUS_IFACE_CONFIG_NAME)
12- iface.set_throttling_limits(self.dn_limit, self.up_limit,
13- reply_handler=dbus_async,
14- error_handler=self.error)
15- if self.bw_limited:
16- iface.enable_bandwidth_throttling(reply_handler=dbus_async,
17- error_handler=self.error)
18- else:
19- iface.disable_bandwidth_throttling(reply_handler=dbus_async,
20- error_handler=self.error)
21- except DBusException, e:
22- self.error(str(e))
23+ if self.sdtool.is_files_sync_enabled():
24+ self.sdtool.set_throttling_limits(self.dn_limit or -1,
25+ self.up_limit or -1)
26+ self.sdtool.enable_throttling(self.bw_limited)
27
28 def handle_bw_controls_changed(self, *a):
29 """
30@@ -242,6 +231,8 @@
31
32 Start a timer to sync with syncdaemon too.
33 """
34+ if not self.sdtool.is_files_sync_enabled():
35+ return
36 # Remove the timeout ...
37 if self._update_id != 0:
38 gobject.source_remove(self._update_id)
39@@ -307,9 +298,15 @@
40
41 This might be better as an error dialog.
42 """
43- self.clear_devices_view()
44- self.status_label.set_markup("<b>Error:</b> %s" % msg)
45 logger.error(msg)
46+ dialog = gtk.MessageDialog(self.get_toplevel(),
47+ gtk.DIALOG_DESTROY_WITH_PARENT | gtk.MODAL,
48+ gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
49+ 'Error')
50+ dialog.format_secondary_text(str(msg))
51+ dialog.run()
52+ while gtk.events_pending():
53+ gtk.main_iteration()
54
55 def get_devices(self):
56 """
57@@ -377,19 +374,22 @@
58
59 token = get_access_token(self.keyring)
60
61+ fsync_enabled = self.sdtool.is_files_sync_enabled()
62+
63 if not self.devices:
64- # a stopgap device so you can at least try to connect
65- self.devices = [{'kind': 'Computer',
66- 'description': _("<LOCAL MACHINE>"),
67- 'token': token.key if token else '',
68- 'FAKE': 'YES'}]
69+ if fsync_enabled:
70+ # a stopgap device so you can at least try to connect
71+ self.devices = [{'kind': 'Computer',
72+ 'description': _("<LOCAL MACHINE>"),
73+ 'token': token.key if token else '',
74+ 'FAKE': 'YES'}]
75 else:
76 self.resize(len(self.devices)+1, 3)
77
78 self.status_label.set_label("")
79
80 i = 0
81- for row in self.devices:
82+ for row in self.devices or ():
83 i += 1
84 img = gtk.Image()
85 img.set_from_icon_name(row['kind'].lower(), gtk.ICON_SIZE_DND)
86@@ -403,7 +403,8 @@
87 butn.connect('clicked', self.remove,
88 row['kind'], row.get('token'))
89 self.attach(butn, 2, 3, i, i+1, xoptions=0, yoptions=0)
90- if token and row.get('token') == token.key or 'FAKE' in row:
91+ if ((token and row.get('token') == token.key or 'FAKE' in row)
92+ and fsync_enabled):
93 self.bw_chk = ck_btn = gtk.CheckButton(
94 _("_Limit Bandwidth Usage"))
95 ck_btn.set_active(self.bw_limited)
96@@ -427,8 +428,9 @@
97 dn_lbl.set_mnemonic_widget(dn_btn)
98 ck_btn.connect('toggled', self.handle_bw_checkbox_toggled,
99 up_lbl, up_btn, dn_lbl, dn_btn)
100- self.handle_bw_checkbox_toggled(ck_btn,
101- up_lbl, up_btn, dn_lbl, dn_btn)
102+ if fsync_enabled:
103+ self.handle_bw_checkbox_toggled(ck_btn, up_lbl, up_btn,
104+ dn_lbl, dn_btn)
105
106 self.conn_btn = gtk.Button(_("Connect"))
107 if self.connected is None:
108@@ -532,6 +534,17 @@
109
110 # SD Tool object
111 self.sdtool = SyncDaemonTool(self.__bus)
112+ if self.sdtool.is_files_sync_enabled():
113+ self._hookup_dbus()
114+ else:
115+ self.status_label.set_text(_("Disconnected"))
116+
117+ logger.debug("starting")
118+
119+ def _hookup_dbus(self):
120+ """
121+ Hook up dbus
122+ """
123 self.sdtool.get_status().addCallbacks(self.__got_state,
124 self.__sd_error)
125
126@@ -554,7 +567,6 @@
127 except DBusException, e:
128 self.__dbus_error(e)
129
130- logger.debug("starting")
131
132 def __dbus_error(self, error):
133 """Error getting throttling config."""
134@@ -595,6 +607,8 @@
135 def __handle_response(self, dialog, response):
136 """Handle the dialog's response."""
137 self.hide()
138+ while gtk.events_pending():
139+ gtk.main_iteration()
140 self.devices.handle_bw_controls_changed()
141 gobject.timeout_add_seconds(5, gtk.main_quit)
142
143@@ -767,6 +781,10 @@
144 self.sdtool.enable_files_sync(enabled).addCallbacks(
145 lambda _: dbus_async,
146 self.__sd_error)
147+ def sd_enabled(_):
148+ self._hookup_dbus()
149+ self.sdtool.connect()
150+ self.devices.list_devices()
151 def sd_error(error):
152 self.files_check.set_active(False)
153 self.files_check.set_sensitive(False)
154@@ -774,18 +792,22 @@
155 self.__sd_error(error)
156
157 if enabled:
158- self.sdtool.start().addErrback(sd_error)
159+ self.sdtool.start().addCallbacks(sd_enabled,
160+ sd_error)
161 if self.ums_id:
162 self.music_check.set_sensitive(True)
163 if self.music_check.get_active():
164 self.__music_check_toggled(self.music_check)
165 else:
166- self.sdtool.quit()
167+ self.sdtool.quit().addCallback(
168+ lambda _: self.devices.list_devices())
169 self.music_check.set_sensitive(False)
170
171 def music_check_toggled(self, checkbutton):
172 """Handle toggling the music download service."""
173 if not self.files_check.get_active() or not self.ums_id:
174+ checkbutton.set_sensitive(False)
175+ checkbutton.set_active(False)
176 return
177 enabled = checkbutton.get_active()
178 def got_error(error):
179@@ -801,11 +823,6 @@
180
181 def get_syncdaemon_sync_config(self):
182 """Update the files/music sync config from syncdaemon."""
183- def got_fs_err(error):
184- self.files_check.set_sensitive(False)
185- self.music_check.set_sensitive(False)
186- self.__sd_error(error)
187-
188 def got_ms_err(error):
189 self.music_check.set_sensitive(False)
190 self.__sd_error(error)
191@@ -822,11 +839,8 @@
192 else:
193 self.music_check.set_active(False)
194
195- def got_fs(enabled):
196- self.files_check.set_active(enabled)
197-
198 self.sdtool.get_folder_info(U1MSPATH).addCallbacks(got_info, got_ms_err)
199- self.sdtool.is_files_sync_enabled().addCallbacks(got_fs, got_fs_err)
200+ self.files_check.set_active(self.sdtool.is_files_sync_enabled())
201
202 def connect_file_sync_callbacks(self):
203 """Connect the file sync checkbox callbacks."""
204@@ -1018,7 +1032,7 @@
205 fbox.show()
206
207 self.files_check = gtk.CheckButton(_("_File Synchronization"))
208- self.files_check.set_active(True)
209+ self.files_check.set_active(False)
210 fbox.pack_start(self.files_check, False, False)
211 self.files_check.show()
212
213@@ -1029,6 +1043,7 @@
214
215 self.music_check = gtk.CheckButton(_("_Music Download"))
216 self.music_check.set_active(True)
217+ self.music_check.set_sensitive(False)
218 alignment.add(self.music_check)
219 self.music_check.show()
220
221@@ -1058,7 +1073,8 @@
222 self.dialog.request_quota_info()
223 self.dialog.request_account_info()
224 self.dialog.devices.get_devices()
225- if self.dialog.visible:
226+ # watch it! jaunty has no 'get_visible' method
227+ if self.dialog.get_property('visible'):
228 self.dialog.present_with_time(int(time.time()))
229
230 def got_newcredentials(self, realm, consumer_key):
231
232=== modified file 'tests/test_preferences.py'
233--- tests/test_preferences.py 2010-03-30 20:17:54 +0000
234+++ tests/test_preferences.py 2010-04-14 23:56:26 +0000
235@@ -25,12 +25,34 @@
236 from contrib.testing.testcase import DBusTwistedTestCase, FakeLogin
237 from twisted.internet import defer
238 from twisted.python.failure import Failure
239-from ubuntuone.syncdaemon import dbus_interface
240+from ubuntuone.syncdaemon import dbus_interface, tools
241+
242+class SyncDaemonTool(tools.SyncDaemonTool):
243+ """A subclass of tools.SyncDaemonTool that keep track of the deferreds."""
244+
245+ def __init__(self, *args, **kwargs):
246+ super(SyncDaemonTool, self).__init__(*args, **kwargs)
247+ self._deferreds = set()
248+
249+ def __getattribute__(self, attr):
250+ attribute = super(SyncDaemonTool, self).__getattribute__(attr)
251+ import inspect
252+ if inspect.ismethod(attribute) or inspect.isfunction(attribute):
253+ def wrapper(*args, **kwargs):
254+ value = attribute(*args, **kwargs)
255+ if isinstance(value, defer.Deferred):
256+ self._deferreds.add(value)
257+ return value
258+ return wrapper
259+ else:
260+ return attribute
261+
262
263 class InvalidSignalError(Exception):
264 """Exception for when we get the wrong signal called."""
265 pass
266
267+
268 class PreferencesTests(MockerTestCase, DBusTwistedTestCase):
269 """Basic tests for the ubuntuone-preferences app."""
270
271@@ -72,7 +94,9 @@
272 self.mocker.result(None)
273
274 self.u1prefs.make_rest_request = self.make_rest_request
275+ self.u1prefs.SyncDaemonTool = SyncDaemonTool
276
277+ @defer.inlineCallbacks
278 def tearDown(self):
279 # collect all signal receivers registered during the test
280 signal_receivers = set()
281@@ -81,13 +105,10 @@
282 for matches in group.values():
283 for match in matches.values():
284 signal_receivers.update(match)
285- d = self.cleanup_signal_receivers(signal_receivers)
286- def shutdown(r):
287- self.oauth.shutdown()
288- dbus_interface.DBUS_PATH_AUTH = self._old_path
289- d.addBoth(shutdown)
290- d.addBoth(lambda _: DBusTwistedTestCase.tearDown(self))
291- return d
292+ yield self.cleanup_signal_receivers(signal_receivers)
293+ self.oauth.shutdown()
294+ dbus_interface.DBUS_PATH_AUTH = self._old_path
295+ yield DBusTwistedTestCase.tearDown(self)
296
297 def make_rest_request(self, url=None, method='GET',
298 callback=None, keyring=None):
299@@ -213,6 +234,7 @@
300 dialog.update_quota_display(1024, 2048)
301 self.assertEqual(dialog.usage_graph.get_fraction(), 0.5)
302 dialog.destroy()
303+ return defer.DeferredList(dialog.sdtool._deferreds)
304
305 def test_request_quota_info(self):
306 """Test that we can request the quota info properly."""
307@@ -224,6 +246,7 @@
308 dialog.request_quota_info()
309 self.assertEqual(dialog.usage_graph.get_fraction(), 0.5)
310 dialog.destroy()
311+ return defer.DeferredList(dialog.sdtool._deferreds)
312
313 def test_no_overquota_notice_on_low_usage(self):
314 """Test that the quota notice is not visible if usage is low."""
315@@ -237,6 +260,7 @@
316 # and the icon should be blank, too
317 self.assertEqual(dialog.overquota_img.get_icon_name()[0], None)
318 dialog.destroy()
319+ return defer.DeferredList(dialog.sdtool._deferreds)
320
321 def test_overquota_notice_and_upgrade_offer_on_free_high_usage(self):
322 """Test that the quota notice is visible if usage is 95%.
323@@ -257,6 +281,7 @@
324 self.assertEqual(dialog.overquota_img.get_icon_name()[0],
325 'dialog-information')
326 dialog.destroy()
327+ return defer.DeferredList(dialog.sdtool._deferreds)
328
329 def test_overquota_notice_and_not_upgrade_offer_on_paid_high_usage(self):
330 """Test that the quota notice is visible if usage is 95%.
331@@ -278,6 +303,7 @@
332 self.assertEqual(dialog.overquota_img.get_icon_name()[0],
333 'dialog-information')
334 dialog.destroy()
335+ return defer.DeferredList(dialog.sdtool._deferreds)
336
337 def test_overquota_warning_and_upgrade_offer_there_on_free_over_quota(self):
338 """Test that the quota notice is visible if usage is 100%.
339@@ -298,6 +324,7 @@
340 self.assertEqual(dialog.overquota_img.get_icon_name()[0],
341 'dialog-warning')
342 dialog.destroy()
343+ return defer.DeferredList(dialog.sdtool._deferreds)
344
345 def test_overquota_warning_there_on_paid_over_quota(self):
346 """Test that the quota notice is visible if usage is 100%."""
347@@ -313,6 +340,7 @@
348 self.assertEqual(dialog.overquota_img.get_icon_name()[0],
349 'dialog-warning')
350 dialog.destroy()
351+ return defer.DeferredList(dialog.sdtool._deferreds)
352
353 def test_request_account_info(self):
354 """Test that we can request the account info properly."""
355@@ -336,6 +364,7 @@
356 self.assertEqual(dialog.plan_label.get_text(), 'Paid')
357 self.assertFalse(dialog.upgrade_link.get_visible())
358 dialog.destroy()
359+ return defer.DeferredList(dialog.sdtool._deferreds)
360
361 def test_toggle_bookmarks(self):
362 """Test toggling the bookmarks service on/off."""
363@@ -353,6 +382,8 @@
364 self.assertFalse(dialog.bookmarks_check.get_active())
365 dialog.bookmarks_check.set_active(True)
366 self.assertTrue(dialog.bookmarks_check.get_active())
367+ dialog.destroy()
368+ return defer.DeferredList(dialog.sdtool._deferreds)
369
370 def test_toggle_contacts(self):
371 """Test toggling the contacts service on/off."""
372@@ -370,6 +401,9 @@
373 self.assertFalse(dialog.abook_check.get_active())
374 dialog.abook_check.set_active(True)
375 self.assertTrue(dialog.abook_check.get_active())
376+ dialog.destroy()
377+ return defer.DeferredList(dialog.sdtool._deferreds)
378+
379
380 def test_toggle_files(self):
381 """Test toggling the files service on/off."""
382@@ -382,6 +416,8 @@
383 self.assertFalse(dialog.files_check.get_active())
384 dialog.files_check.set_active(True)
385 self.assertTrue(dialog.files_check.get_active())
386+ dialog.destroy()
387+ return defer.DeferredList(dialog.sdtool._deferreds)
388
389 def test_toggle_files_and_music(self):
390 """Test toggling the files and music services on/off."""
391@@ -417,6 +453,8 @@
392 dialog.files_check.set_active(False)
393 self.assertFalse(dialog.files_check.get_active())
394 self.assertFalse(dialog.music_check.props.sensitive)
395+ dialog.destroy()
396+ return defer.DeferredList(dialog.sdtool._deferreds)
397
398 def test_login_check(self):
399 """Test that our login check works correctly."""
400
401=== modified file 'ubuntuone/syncdaemon/tools.py'
402--- ubuntuone/syncdaemon/tools.py 2010-04-05 16:51:53 +0000
403+++ ubuntuone/syncdaemon/tools.py 2010-04-14 23:56:26 +0000
404@@ -31,6 +31,7 @@
405 DBUS_IFACE_PUBLIC_FILES_NAME,
406 DBUS_IFACE_CONFIG_NAME,
407 )
408+from ubuntuone.syncdaemon.config import get_user_config
409 from dbus.lowlevel import SignalMessage, MethodCallMessage, ErrorMessage
410 from dbus.exceptions import DBusException
411 from twisted.internet import defer, reactor
412@@ -704,25 +705,27 @@
413 def is_files_sync_enabled(self):
414 """Check if files sync is enabled."""
415 self.log.debug('is_files_sync_enabled')
416- d = defer.Deferred()
417- config_client = DBusClient(self.bus, '/config',
418- DBUS_IFACE_CONFIG_NAME)
419- config_client.call_method('files_sync_enabled',
420- reply_handler=d.callback,
421- error_handler=d.errback)
422- return d
423+ return get_user_config().get_files_sync_enabled()
424
425 def enable_files_sync(self, enabled):
426 """Enable/disable files sync."""
427 self.log.debug('enable_files_sync %d', enabled)
428- d = defer.Deferred()
429- config_client = DBusClient(self.bus, '/config',
430- DBUS_IFACE_CONFIG_NAME)
431- config_client.call_method('set_files_sync_enabled',
432- enabled,
433- reply_handler=d.callback,
434- error_handler=d.errback)
435- return d
436+ config = get_user_config()
437+ if config.get_files_sync_enabled():
438+ d = defer.Deferred()
439+ config_client = DBusClient(self.bus, '/config',
440+ DBUS_IFACE_CONFIG_NAME)
441+ config_client.call_method('set_files_sync_enabled',
442+ enabled,
443+ reply_handler=d.callback,
444+ error_handler=d.errback)
445+ return d
446+ else:
447+ if enabled:
448+ config.set_files_sync_enabled(True)
449+ config.save()
450+ self.start()
451+ return defer.succeed(None)
452
453
454 # callbacks used by u1sdtool script

Subscribers

People subscribed via source and target branches