Merge lp:~nataliabidart/ubuntuone-client/autoconnect into lp:ubuntuone-client

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 772
Merged at revision: 770
Proposed branch: lp:~nataliabidart/ubuntuone-client/autoconnect
Merge into: lp:ubuntuone-client
Diff against target: 398 lines (+194/-13)
10 files modified
bin/ubuntuone-preferences (+10/-4)
data/syncdaemon.conf (+5/-0)
tests/platform/linux/test_dbus.py (+43/-0)
tests/syncdaemon/test_config.py (+52/-2)
tests/syncdaemon/test_main.py (+36/-3)
tests/test_preferences.py (+5/-2)
ubuntuone/platform/linux/__init__.py (+15/-1)
ubuntuone/platform/linux/dbus_interface.py (+14/-0)
ubuntuone/syncdaemon/config.py (+9/-0)
ubuntuone/syncdaemon/main.py (+5/-1)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-client/autoconnect
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Chad Miller (community) Approve
Review via email: mp+43385@code.launchpad.net

Commit message

* Added new config option 'autoconnect' (LP: #688694).

Description of the change

To test, you should:

* quit syncdaemon (u1sdtool -q)

* edit ~/.config/ubuntuone/syncdaemon.conf and under the __main__ section add:
autoconnect = True

* ./autogen.sh && make

* start syncdaemon from this branch with:
PYTHONPATH=. ./bin/ubuntuone-syncdaemon

Monitor syncdaemon status either thru the logs or using u1sdtool and you'll see how it progresses further than READY, reaching QUEUE_MANAGER state.

To post a comment you must log in.
Revision history for this message
Chad Miller (cmiller) wrote :

Works for me.

review: Approve
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

looks good, tests pass.

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

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-11-30 17:53:14 +0000
3+++ bin/ubuntuone-preferences 2010-12-10 22:10:15 +0000
4@@ -123,6 +123,7 @@
5 except DBusException, e:
6 error_handler(e)
7
8+
9 def really_do_rest_request(url, method, conn):
10 """Second-order helper that does the REST request.
11
12@@ -136,6 +137,7 @@
13 conn.send(result)
14 logger.debug("end really_do_rest_request (%s:%s)", method, url)
15
16+
17 def do_rest_request(proc, conn, callback):
18 """Helper that handles the REST request."""
19 pid = os.getpid()
20@@ -149,6 +151,7 @@
21 callback(result)
22 logger.debug("end do_rest_request (%d)", pid)
23
24+
25 def make_rest_request(url=None, method='GET', callback=None):
26 """Helper that makes an oauth-wrapped REST request."""
27 logger.debug("make_rest_request (%s:%s)", method, url)
28@@ -159,6 +162,7 @@
29 Thread(target=do_rest_request, args=(p, conn1, callback)).start()
30 logger.debug("end make_rest_request (%s:%s)", method, url)
31
32+
33 class DevicesWidget(gtk.Table):
34 """
35 the Devices tab.
36@@ -471,9 +475,9 @@
37 DBUS_CREDENTIALS_PATH,
38 follow_name_owner_changes=True)
39 iface = dbus.Interface(client, DBUS_CREDENTIALS_IFACE)
40- iface.clear_token(clientdefs.APP_NAME,
41- reply_handler=local_removal_cb,
42- error_handler=self.error)
43+ iface.clear_credentials(clientdefs.APP_NAME, {},
44+ reply_handler=local_removal_cb,
45+ error_handler=self.error)
46 except DBusException, e:
47 self.error(e)
48
49@@ -1054,8 +1058,10 @@
50 self.present()
51 logger.info("Got credentials for %s", app_name)
52
53- def got_credentialserror(self, app_name, message, detailed_error):
54+ def got_credentialserror(self, app_name, error_dict):
55 """Got an error during authentication."""
56+ message = error_dict.get('error_msg', '')
57+ detailed_error = error_dict.get('detailed_error', '')
58 if app_name == clientdefs.APP_NAME:
59 logger.error("Credentials error for %s: %s - %s" %
60 (app_name, message, detailed_error))
61
62=== modified file 'data/syncdaemon.conf'
63--- data/syncdaemon.conf 2010-11-12 21:39:37 +0000
64+++ data/syncdaemon.conf 2010-12-10 22:10:15 +0000
65@@ -64,6 +64,11 @@
66 udf_autosubscribe.help = Autosubsribe to new User Defined Folders, 'off' by default.
67 (accepted values: 1/0, on/off, true/false and yes/no)
68
69+autoconnect.default = True
70+autoconnect.parser = bool
71+autoconnect.help = Autoconnect the syncdaemon when is ready to start file synchronization against the server, 'on' by default.
72+ (accepted values: 1/0, on/off, true/false and yes/no)
73+
74 ignore.parser = lines
75 ignore.help = The list of (Python, not bash) regexes of the files that
76 SD should ignore.
77
78=== modified file 'tests/platform/linux/test_dbus.py'
79--- tests/platform/linux/test_dbus.py 2010-12-06 21:34:56 +0000
80+++ tests/platform/linux/test_dbus.py 2010-12-10 22:10:15 +0000
81@@ -2425,6 +2425,49 @@
82 error_handler=self.error_handler)
83 return d
84
85+ def test_autoconnect_enabled(self):
86+ """Test for Config.autoconnect_enabled."""
87+ client = self.get_client()
88+ d = defer.Deferred()
89+
90+ def reply_handler_disabled(result):
91+ """Handle the reply."""
92+ self.assertFalse(result)
93+ config.get_user_config().set_autoconnect(not result)
94+ d.callback(True)
95+
96+ def reply_handler_enabled(result):
97+ """Handle the reply."""
98+ self.assertTrue(result)
99+ config.get_user_config().set_autoconnect(not result)
100+ client.call_method('autoconnect_enabled',
101+ reply_handler=reply_handler_disabled,
102+ error_handler=self.error_handler)
103+
104+ client.call_method('autoconnect_enabled',
105+ reply_handler=reply_handler_enabled,
106+ error_handler=self.error_handler)
107+ return d
108+
109+ def test_set_autoconnect_enabled(self):
110+ """Test for Config.set_autoconnect_enabled."""
111+ client = self.get_client()
112+ d = defer.Deferred()
113+ orig = config.get_user_config().get_autoconnect()
114+ # restore autoconnect to original value
115+ self.addCleanup(lambda: config.get_user_config().set_autoconnect(orig))
116+
117+ def reply_handler(_):
118+ """Handle the reply."""
119+ self.assertEqual(config.get_user_config().get_autoconnect(),
120+ not orig)
121+ d.callback(True)
122+
123+ client.call_method('set_autoconnect_enabled', not orig,
124+ reply_handler=reply_handler,
125+ error_handler=self.error_handler)
126+ return d
127+
128
129 class DBusOAuthTestCase(BaseTwistedTestCase):
130 """Tests the interaction between dbus_interface and ubuntu-sso-client."""
131
132=== modified file 'tests/syncdaemon/test_config.py'
133--- tests/syncdaemon/test_config.py 2010-11-30 17:53:14 +0000
134+++ tests/syncdaemon/test_config.py 2010-12-10 22:10:15 +0000
135@@ -235,7 +235,8 @@
136
137 def test_load_udf_autosubscribe(self):
138 """Test load/set/override of udf_autosubscribe config value."""
139- conf_file = os.path.join(self.test_root, 'test_udf_autosubscribe_config.conf')
140+ conf_file = os.path.join(self.test_root,
141+ 'test_udf_autosubscribe_config.conf')
142 # write some throttling values to the config file
143 with open(conf_file, 'w') as fp:
144 fp.write('[__main__]\n')
145@@ -275,11 +276,60 @@
146 overridden_opts = [('__main__', 'udf_autosubscribe', False)]
147 conf.override_options(overridden_opts)
148 self.assertFalse(conf.get_udf_autosubscribe())
149- self.assertFalse(conf.get_udf_autosubscribe() == conf_orig.get_udf_autosubscribe())
150+ self.assertNotEqual(conf.get_udf_autosubscribe(),
151+ conf_orig.get_udf_autosubscribe())
152 conf.save()
153 conf_1 = config._Config(conf_file)
154 self.assertEquals(True, conf_1.get_udf_autosubscribe())
155
156+ def test_load_autoconnect(self):
157+ """Test load/set/override of autoconnect config value."""
158+ conf_file = os.path.join(self.test_root,
159+ 'test_autoconnect_config.conf')
160+ # ensure that autoconnect is True
161+ with open(conf_file, 'w') as fp:
162+ fp.write('[__main__]\n')
163+ fp.write('autoconnect = True\n')
164+
165+ # keep a original around
166+ conf_orig = config._Config(conf_file)
167+
168+ # assert default is correct
169+ self.assertTrue(conf_orig.get_autoconnect(),
170+ 'autoconnect is True by default.')
171+
172+ # load the config
173+ conf = config._Config(conf_file)
174+ self.assertTrue(conf.get_autoconnect())
175+
176+ # change it to False
177+ conf.set_autoconnect(False)
178+ self.assertFalse(conf.get_autoconnect())
179+
180+ # save, load and check
181+ conf.save()
182+ conf_1 = config._Config(conf_file)
183+ self.assertFalse(conf_1.get_autoconnect())
184+ # change it to True
185+ conf.set_autoconnect(True)
186+ self.assertTrue(conf.get_autoconnect())
187+ # save, load and check
188+ conf.save()
189+ conf_1 = config._Config(conf_file)
190+ self.assertTrue(conf_1.get_autoconnect())
191+
192+ # load the config, check the override of the value
193+ conf = config._Config(conf_file)
194+ self.assertTrue(conf.get_autoconnect())
195+ overridden_opts = [('__main__', 'autoconnect', False)]
196+ conf.override_options(overridden_opts)
197+ self.assertFalse(conf.get_autoconnect())
198+ self.assertNotEqual(conf.get_autoconnect(),
199+ conf_orig.get_autoconnect())
200+ conf.save()
201+ conf_1 = config._Config(conf_file)
202+ self.assertEquals(True, conf_1.get_autoconnect())
203+
204
205 class ConfigglueParsersTests(BaseTwistedTestCase):
206 """Tests for our custom configglue parsers"""
207
208=== modified file 'tests/syncdaemon/test_main.py'
209--- tests/syncdaemon/test_main.py 2010-11-30 17:53:14 +0000
210+++ tests/syncdaemon/test_main.py 2010-12-10 22:10:15 +0000
211@@ -23,9 +23,9 @@
212
213 from twisted.internet import defer, reactor
214
215-from ubuntuone.syncdaemon.main import Main
216+from ubuntuone.syncdaemon import main as main_mod
217 from contrib.testing.testcase import (
218- BaseTwistedTestCase,
219+ BaseTwistedTestCase, FAKED_CREDENTIALS,
220 )
221
222
223@@ -56,9 +56,10 @@
224 dns_srv=False, ssl=False,
225 mark_interval=60,
226 handshake_timeout=2,
227+ oauth_credentials=FAKED_CREDENTIALS,
228 glib_loop=DBusGMainLoop(set_as_default=True))
229 params.update(kwargs)
230- m = Main(**params)
231+ m = main_mod.Main(**params)
232 m.local_rescan = lambda *_: m.event_q.push('SYS_LOCAL_RESCAN_DONE')
233 return m
234
235@@ -172,3 +173,35 @@
236 self.assertTrue(os.path.exists(self.shares))
237 self.assertTrue(os.path.exists(self.root))
238 main.shutdown()
239+
240+ def test_connect_if_autoconnect_is_enabled(self):
241+ """If autoconnect option is enabled, connect the syncdaemon."""
242+ user_config = main_mod.config.get_user_config()
243+ orig = user_config.get_autoconnect()
244+ user_config.set_autoconnect(True)
245+ self.addCleanup(lambda: user_config.set_autoconnect(orig))
246+
247+ self.connect_called = False
248+ self.patch(main_mod.ubuntuone.platform.ExternalInterface, 'connect',
249+ lambda *a: setattr(self, 'connect_called', True))
250+
251+ main = self.build_main()
252+ self.addCleanup(lambda: main.shutdown())
253+
254+ self.assertTrue(self.connect_called)
255+
256+ def test_dont_connect_if_autoconnect_is_disabled(self):
257+ """If autoconnect option is disabled, do not connect the syncdaemon."""
258+ user_config = main_mod.config.get_user_config()
259+ orig = user_config.get_autoconnect()
260+ user_config.set_autoconnect(False)
261+ self.addCleanup(lambda: user_config.set_autoconnect(orig))
262+
263+ self.connect_called = False
264+ self.patch(main_mod.ubuntuone.platform.ExternalInterface, 'connect',
265+ lambda *a: setattr(self, 'connect_called', True))
266+
267+ main = self.build_main()
268+ self.addCleanup(lambda: main.shutdown())
269+
270+ self.assertFalse(self.connect_called)
271
272=== modified file 'tests/test_preferences.py'
273--- tests/test_preferences.py 2010-11-30 17:53:14 +0000
274+++ tests/test_preferences.py 2010-12-10 22:10:15 +0000
275@@ -561,8 +561,11 @@
276
277 def test_got_credentialserror(self):
278 """Test CredentialsError signal."""
279- self.login_handler.got_credentialserror(clientdefs.APP_NAME, "Error", "Detailed error")
280- self.assertTrue(self.memento.check_error(clientdefs.APP_NAME, "Error", "Detailed error"))
281+ error_dict = {'error_msg': 'Test', 'detailed_error': 'My bad'}
282+ self.login_handler.got_credentialserror(clientdefs.APP_NAME,
283+ error_dict)
284+ self.assertTrue(self.memento.check_error(clientdefs.APP_NAME,
285+ *error_dict.values()))
286
287 def test_got_authdenied(self):
288 """Test AuthorizationDenied signal."""
289
290=== modified file 'ubuntuone/platform/linux/__init__.py'
291--- ubuntuone/platform/linux/__init__.py 2010-12-06 21:34:56 +0000
292+++ ubuntuone/platform/linux/__init__.py 2010-12-10 22:10:15 +0000
293@@ -38,12 +38,15 @@
294 open_file,
295 rename,
296 )
297-from ubuntuone.platform.linux.vm_helper import create_shares_link, get_udf_path_name, get_udf_path, get_share_path, VMMetadataUpgraderMixIn
298+from ubuntuone.platform.linux.vm_helper import (create_shares_link,
299+ get_udf_path_name, get_udf_path, get_share_path, VMMetadataUpgraderMixIn)
300 from ubuntuone.platform.linux import tools
301 from filesystem_notifications import FilesystemMonitor
302
303
304 class ExternalInterface(object):
305+ """An ExternalInterface implemented with a DBus interface."""
306+
307 def __init__(self, main, glib_loop=False, broadcast_events=False,
308 dbus_iface=None):
309 # avoid circular dependencies
310@@ -63,8 +66,19 @@
311 self.dbus_iface = dbus_iface
312 self.bus = None
313
314+ def _get_credentials(self):
315+ return self.dbus_iface.oauth_credentials
316+
317+ def _set_credentials(self, credentials):
318+ self.dbus_iface.oauth_credentials = credentials
319+
320+ oauth_credentials = property(fget=_get_credentials, fset=_set_credentials)
321+
322 def change_notification(self):
323 self.dbus_iface.status.emit_content_queue_changed()
324
325 def shutdown(self, with_restart):
326 self.dbus_iface.shutdown(with_restart)
327+
328+ def connect(self):
329+ self.dbus_iface.connect()
330
331=== modified file 'ubuntuone/platform/linux/dbus_interface.py'
332--- ubuntuone/platform/linux/dbus_interface.py 2010-12-09 13:38:46 +0000
333+++ ubuntuone/platform/linux/dbus_interface.py 2010-12-10 22:10:15 +0000
334@@ -1474,6 +1474,20 @@
335 logger.debug('called files_sync_enabled')
336 return config.get_user_config().get_files_sync_enabled()
337
338+ @dbus.service.method(DBUS_IFACE_CONFIG_NAME,
339+ in_signature='', out_signature='b')
340+ def autoconnect_enabled(self):
341+ """Return the autoconnect config value."""
342+ return config.get_user_config().get_autoconnect()
343+
344+ @dbus.service.method(DBUS_IFACE_CONFIG_NAME,
345+ in_signature='b', out_signature='')
346+ def set_autoconnect_enabled(self, enabled):
347+ """Enable syncdaemon autoconnect."""
348+ user_config = config.get_user_config()
349+ user_config.set_autoconnect(enabled)
350+ user_config.save()
351+
352
353 class Folders(DBusExposedObject):
354 """A dbus interface to interact with User Defined Folders"""
355
356=== modified file 'ubuntuone/syncdaemon/config.py'
357--- ubuntuone/syncdaemon/config.py 2010-08-11 14:05:23 +0000
358+++ ubuntuone/syncdaemon/config.py 2010-12-10 22:10:15 +0000
359@@ -343,6 +343,15 @@
360 def get_files_sync_enabled(self):
361 return self.get_parsed(MAIN, 'files_sync_enabled')
362
363+ @requires_section(MAIN)
364+ def set_autoconnect(self, enabled):
365+ self.set(MAIN, 'autoconnect', str(enabled))
366+
367+ @requires_section(MAIN)
368+ def get_autoconnect(self):
369+ return self.get_parsed(MAIN, 'autoconnect')
370+
371+
372
373 def configglue(fileobj, *filenames, **kwargs):
374 """Populate an OptionParser with options and defaults taken from a
375
376=== modified file 'ubuntuone/syncdaemon/main.py'
377--- ubuntuone/syncdaemon/main.py 2010-12-06 23:47:32 +0000
378+++ ubuntuone/syncdaemon/main.py 2010-12-10 22:10:15 +0000
379@@ -78,7 +78,7 @@
380 mark_interval=120, broadcast_events=False, handshake_timeout=30,
381 shares_symlink_name='Shared With Me',
382 read_limit=None, write_limit=None, throttling_enabled=False,
383- ignore_files=None):
384+ ignore_files=None, oauth_credentials=None):
385 self.root_dir = root_dir
386 self.shares_dir = shares_dir
387 self.shares_dir_link = os.path.join(self.root_dir, shares_symlink_name)
388@@ -122,6 +122,10 @@
389
390 self.external = ubuntuone.platform.ExternalInterface(
391 self, glib_loop, broadcast_events)
392+ self.external.oauth_credentials = oauth_credentials
393+ if user_config.get_autoconnect():
394+ self.external.connect()
395+
396 self.action_q.content_queue.set_change_notification_cb(
397 self.external.change_notification)
398 self.zg_listener = event_logging.ZeitgeistListener(self.fs, self.vm)

Subscribers

People subscribed via source and target branches