Merge lp:~nataliabidart/ubuntuone-control-panel/stop-backend into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 117
Merged at revision: 115
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/stop-backend
Merge into: lp:ubuntuone-control-panel
Diff against target: 244 lines (+94/-11)
7 files modified
ubuntuone/controlpanel/backend.py (+9/-1)
ubuntuone/controlpanel/dbus_service.py (+16/-6)
ubuntuone/controlpanel/gtk/gui.py (+7/-0)
ubuntuone/controlpanel/gtk/tests/__init__.py (+1/-1)
ubuntuone/controlpanel/gtk/tests/test_gui_basic.py (+5/-0)
ubuntuone/controlpanel/integrationtests/test_dbus_service.py (+38/-3)
ubuntuone/controlpanel/tests/test_backend.py (+18/-0)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/stop-backend
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+55193@code.launchpad.net

Commit message

- Stop the control panel backend once the UI is done (LP: #704434).

Description of the change

To test IRL, please do the following:

* killall ubuntuone-control-panel-backend

Then, run in two terminals:

nessita@dali:~/canonical/u1/cp/stop-backend$ DEBUG=True PYTHONPATH=. ./bin/ubuntuone-control-panel-backend

nessita@dali:~/canonical/u1/cp/stop-backend$ DEBUG=True PYTHONPATH=. ./bin/ubuntuone-control-panel-gtk

Then close the control panel UI. Check that there is no ubuntuone-control-panel-backend process running.

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

Code looks great, closing the panel stops the backend

review: Approve
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

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 2011-03-02 19:54:09 +0000
3+++ ubuntuone/controlpanel/backend.py 2011-03-28 17:32:28 +0000
4@@ -69,8 +69,9 @@
5 SHARE_TYPE = u'SHARE'
6 NAME_NOT_SET = u'ENAMENOTSET'
7
8- def __init__(self):
9+ def __init__(self, shutdown_func=None):
10 """Initialize the webclient."""
11+ self.shutdown_func = shutdown_func
12 self.wc = WebClient(dbus_client.get_credentials)
13 self._status_changed_handler = None
14 self.status_changed_handler = lambda *a: None
15@@ -478,3 +479,10 @@
16 """Install the extension to sync bookmarks."""
17 # still pending (LP: #673673)
18 returnValue(None)
19+
20+ @log_call(logger.info)
21+ def shutdown(self):
22+ """Stop this service."""
23+ # do any other needed cleanup
24+ if self.shutdown_func is not None:
25+ self.shutdown_func()
26
27=== modified file 'ubuntuone/controlpanel/dbus_service.py'
28--- ubuntuone/controlpanel/dbus_service.py 2011-01-20 14:31:24 +0000
29+++ ubuntuone/controlpanel/dbus_service.py 2011-03-28 17:32:28 +0000
30@@ -538,15 +538,24 @@
31 def InstallBookmarksError(self, error):
32 """Problem installing the extension to sync bookmarks."""
33
34+ #---
35+
36+ @log_call(logger.info)
37+ @method(dbus_interface=DBUS_PREFERENCES_IFACE, in_signature="")
38+ def shutdown(self):
39+ """Shutdown this service."""
40+ self.backend.shutdown()
41+
42
43 def init_mainloop():
44 """Start the DBus mainloop."""
45 DBusGMainLoop(set_as_default=True)
46
47
48-def run_mainloop():
49+def run_mainloop(loop=None):
50 """Run the gobject main loop."""
51- loop = gobject.MainLoop()
52+ if loop is None:
53+ loop = gobject.MainLoop()
54 loop.run()
55
56
57@@ -566,10 +575,10 @@
58 return dbus.service.BusName(DBUS_BUS_NAME, bus=dbus.SessionBus())
59
60
61-def publish_backend(backend=None):
62+def publish_backend(backend=None, shutdown_func=None):
63 """Publish the backend on the DBus."""
64 if backend is None:
65- backend = ControlBackend()
66+ backend = ControlBackend(shutdown_func=shutdown_func)
67 return ControlPanelBackend(backend=backend,
68 object_path=DBUS_PREFERENCES_PATH,
69 bus_name=get_busname())
70@@ -579,7 +588,8 @@
71 """Hook the DBus listeners and start the main loop."""
72 init_mainloop()
73 if register_service():
74- publish_backend()
75- run_mainloop()
76+ loop = gobject.MainLoop()
77+ publish_backend(shutdown_func=loop.quit)
78+ run_mainloop(loop=loop)
79 else:
80 print "Control panel backend already running."
81
82=== modified file 'ubuntuone/controlpanel/gtk/gui.py'
83--- ubuntuone/controlpanel/gtk/gui.py 2011-03-25 20:48:13 +0000
84+++ ubuntuone/controlpanel/gtk/gui.py 2011-03-28 17:32:28 +0000
85@@ -1516,6 +1516,7 @@
86 gtk.Notebook.__init__(self)
87 ControlPanelMixin.__init__(self)
88 gtk.link_button_set_uri_hook(uri_hook)
89+ self.connect('destroy', self.shutdown)
90
91 self.main_window = main_window
92
93@@ -1539,6 +1540,12 @@
94 logger.debug('%s: started (window size %r).',
95 self.__class__.__name__, self.get_size_request())
96
97+ def shutdown(self, *args, **kwargs):
98+ """Shutdown backend."""
99+ logger.info('Shutding down...')
100+ self.backend.shutdown(reply_handler=NO_OP,
101+ error_handler=error_handler)
102+
103 def on_show_overview_panel(self, widget=None):
104 """Show the overview panel."""
105 self.set_current_page(0)
106
107=== modified file 'ubuntuone/controlpanel/gtk/tests/__init__.py'
108--- ubuntuone/controlpanel/gtk/tests/__init__.py 2011-03-01 15:23:01 +0000
109+++ ubuntuone/controlpanel/gtk/tests/__init__.py 2011-03-28 17:32:28 +0000
110@@ -180,7 +180,7 @@
111 'replications_info', 'change_replication_settings', # replications
112 'file_sync_status', 'enable_files', 'disable_files', # files
113 'connect_files', 'disconnect_files',
114- 'restart_files', 'start_files', 'stop_files',
115+ 'restart_files', 'start_files', 'stop_files', 'shutdown',
116 ]
117
118
119
120=== modified file 'ubuntuone/controlpanel/gtk/tests/test_gui_basic.py'
121--- ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-03-25 20:48:13 +0000
122+++ ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-03-28 17:32:28 +0000
123@@ -219,6 +219,11 @@
124
125 self.assert_current_tab_correct(self.ui.overview)
126
127+ def test_backend_is_shutdown_on_close(self):
128+ """When the control panel is closed, the backend is shutdown."""
129+ self.ui.emit('destroy')
130+ self.assert_backend_called('shutdown', ())
131+
132
133 class UbuntuOneBinTestCase(BaseTestCase):
134 """The test suite for a Ubuntu One panel."""
135
136=== modified file 'ubuntuone/controlpanel/integrationtests/test_dbus_service.py'
137--- ubuntuone/controlpanel/integrationtests/test_dbus_service.py 2011-02-16 18:44:08 +0000
138+++ ubuntuone/controlpanel/integrationtests/test_dbus_service.py 2011-03-28 17:32:28 +0000
139@@ -84,12 +84,23 @@
140 rs = self.mocker.replace(rs_name)
141 rs()
142 self.mocker.result(True)
143+
144+ mainloop = "ubuntuone.controlpanel.dbus_service.gobject.MainLoop"
145+ mainloop = self.mocker.replace(mainloop)
146+ mainloop()
147+ loop = self.mocker.mock()
148+ self.mocker.result(loop)
149+
150+ shutdown_func = self.mocker.mock()
151+ loop.quit # pylint: disable=W0104
152+ self.mocker.result(shutdown_func)
153+
154 rml_name = "ubuntuone.controlpanel.dbus_service.run_mainloop"
155 rml = self.mocker.replace(rml_name)
156- rml()
157+ rml(loop=loop)
158 pb_name = "ubuntuone.controlpanel.dbus_service.publish_backend"
159 pb = self.mocker.replace(pb_name)
160- pb()
161+ pb(shutdown_func=shutdown_func)
162 self.mocker.replay()
163 dbus_service.main()
164
165@@ -112,6 +123,10 @@
166 dbus_service.STATUS_KEY: dbus_service.FILE_SYNC_IDLE,
167 }
168 status_changed_handler = None
169+ shutdown_func = None
170+
171+ def __init__(self, shutdown_func=None):
172+ MockBackend.shutdown_func = shutdown_func
173
174 def _process(self, result):
175 """Process the request with the given result."""
176@@ -197,6 +212,10 @@
177 """Install the extension to sync bookmarks."""
178 return self._process(None)
179
180+ def shutdown(self):
181+ """Stop this service."""
182+ self.shutdown_func()
183+
184
185 class DBusServiceTestCase(TestCase):
186 """Test for the DBus service."""
187@@ -289,7 +308,8 @@
188 def setUp(self):
189 super(BaseTestCase, self).setUp()
190 dbus_service.init_mainloop()
191- be = dbus_service.publish_backend(MockBackend())
192+ self.patch(dbus_service, 'ControlBackend', MockBackend)
193+ be = dbus_service.publish_backend()
194 self.addCleanup(be.remove_from_connection)
195 bus = dbus.SessionBus()
196 obj = bus.get_object(bus_name=DBUS_BUS_NAME,
197@@ -691,3 +711,18 @@
198 cpbe = dbus_service.ControlPanelBackend(backend=be)
199
200 self.assertEqual(be.status_changed_handler, cpbe.process_status)
201+
202+
203+class ShutdownTestCase(BaseTestCase):
204+ """Test for the DBus service shurdown."""
205+
206+ @defer.inlineCallbacks
207+ def test_shutdown(self):
208+ """The service can be shutdown."""
209+ called = []
210+ MockBackend.shutdown_func = lambda *a: called.append('shutdown')
211+ self.backend.shutdown(reply_handler=lambda: self.deferred.callback(1),
212+ error_handler=self.got_error)
213+ yield self.deferred
214+
215+ self.assertEqual(called, ['shutdown'])
216
217=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
218--- ubuntuone/controlpanel/tests/test_backend.py 2011-03-02 19:54:09 +0000
219+++ ubuntuone/controlpanel/tests/test_backend.py 2011-03-28 17:32:28 +0000
220@@ -278,6 +278,24 @@
221 result = yield self.be.device_is_local(did)
222 self.assertFalse(result)
223
224+ def test_shutdown_func(self):
225+ """A shutdown_func can be passed as creation parameter."""
226+ f = lambda: None
227+ be = backend.ControlBackend(shutdown_func=f)
228+ self.assertEqual(be.shutdown_func, f)
229+
230+ def test_shutdown_func_is_called_on_shutdown(self):
231+ """The shutdown_func is called on shutdown."""
232+ self.be.shutdown_func = self._set_called
233+ self.be.shutdown()
234+ self.assertEqual(self._called, ((), {}))
235+
236+ def test_shutdown_func_when_none(self):
237+ """The shutdown_func can be None."""
238+ self.be.shutdown_func = None
239+ self.be.shutdown()
240+ # nothing explodes
241+
242
243 class BackendAccountTestCase(BackendBasicTestCase):
244 """Account tests for the backend."""

Subscribers

People subscribed via source and target branches