Merge lp:~dobey/desktopcouch/fix-696968 into lp:desktopcouch

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 244
Merged at revision: 249
Proposed branch: lp:~dobey/desktopcouch/fix-696968
Merge into: lp:desktopcouch
Diff against target: 233 lines (+59/-34)
6 files modified
desktopcouch/application/platform/linux/__init__.py (+0/-3)
desktopcouch/application/plugins/__init__.py (+7/-6)
desktopcouch/application/plugins/tests/test_plugins.py (+44/-0)
desktopcouch/application/plugins/ubuntuone_pairing.py (+3/-2)
desktopcouch/application/service.py (+3/-10)
desktopcouch/application/tests/test_service.py (+2/-13)
To merge this branch: bzr merge lp:~dobey/desktopcouch/fix-696968
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+45252@code.launchpad.net

Commit message

Fix the issues with the plug-in loader to actually load the plug-ins
Move the plug-in loading call to the dbus service startup
Remove the old entry_points code using pkg_resources

Description of the change

This fixes the loading of the plug-ins and adds a bit more testing for it.

However, it is not easily testable at the moment, due to further reaching issues with interaction between dbus, main loops, and os.fork in desktopcouch.

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

Looks good

review: Approve
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Code looks good though I couldn't make a fieldtest.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'desktopcouch/application/platform/linux/__init__.py'
--- desktopcouch/application/platform/linux/__init__.py 2010-12-16 21:13:00 +0000
+++ desktopcouch/application/platform/linux/__init__.py 2011-01-05 15:54:30 +0000
@@ -20,8 +20,6 @@
20import re20import re
21import logging21import logging
2222
23from desktopcouch.application.plugins import load_plugins
24
2523
26def process_is_couchdb(pid):24def process_is_couchdb(pid):
27 """Find if the process with the given pid is couchdb."""25 """Find if the process with the given pid is couchdb."""
@@ -190,6 +188,5 @@
190 from dbus.mainloop.glib import DBusGMainLoop188 from dbus.mainloop.glib import DBusGMainLoop
191 DBusGMainLoop(set_as_default=True)189 DBusGMainLoop(set_as_default=True)
192 set_application_name('desktopcouch service')190 set_application_name('desktopcouch service')
193 load_plugins()
194 from twisted.internet import reactor191 from twisted.internet import reactor
195 return reactor192 return reactor
196193
=== modified file 'desktopcouch/application/plugins/__init__.py'
--- desktopcouch/application/plugins/__init__.py 2010-12-16 22:08:22 +0000
+++ desktopcouch/application/plugins/__init__.py 2011-01-05 15:54:30 +0000
@@ -13,10 +13,10 @@
13# along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.13# along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.
14"""Desktopcouch application plugins."""14"""Desktopcouch application plugins."""
1515
16import logging
16import os17import os
1718
18DESKTOPCOUCH_PLUGIN_PATHS = [os.path.join(19DESKTOPCOUCH_PLUGIN_PATHS = [os.path.join(os.path.dirname(__file__))]
19 os.path.dirname(__file__), 'plugins')]
2020
2121
22def load_plugins():22def load_plugins():
@@ -28,14 +28,15 @@
28 if _file == '__init__':28 if _file == '__init__':
29 continue29 continue
30 elif _file.endswith('.py') and _file != '__init__.py':30 elif _file.endswith('.py') and _file != '__init__.py':
31 plugin_names.add(os.path.join(path, _file))31 plugin_names.add(os.path.join(
32 'desktopcouch', 'application', 'plugins', _file))
32 except OSError:33 except OSError:
33 continue34 continue
3435
35 for name in plugin_names:36 for name in plugin_names:
37 modpath = name.replace(os.path.sep, '.')[:-3]
36 try:38 try:
37 modpath = name.replace(os.path.sep, '.')[:-3]
38 plugin = __import__(modpath, None, None, [''])39 plugin = __import__(modpath, None, None, [''])
39 plugin.plugin_init()40 plugin.plugin_init()
40 except ImportError:41 except (ImportError, AttributeError):
41 pass42 logging.warning('Failed to load plug-in: %s', modpath)
4243
=== added file 'desktopcouch/application/plugins/tests/test_plugins.py'
--- desktopcouch/application/plugins/tests/test_plugins.py 1970-01-01 00:00:00 +0000
+++ desktopcouch/application/plugins/tests/test_plugins.py 2011-01-05 15:54:30 +0000
@@ -0,0 +1,44 @@
1# Copyright 2011 Canonical Ltd.
2#
3# This file is part of desktopcouch.
4#
5# desktopcouch is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License version 3
7# as published by the Free Software Foundation.
8#
9# desktopcouch is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.
16"""Tests for the plug-ins loading."""
17
18import os
19
20from desktopcouch.application import plugins
21from unittest import TestCase
22
23
24class TestLoadPlugins(TestCase):
25 """Tests for loading plug-ins."""
26
27 def test_load_plugins(self):
28 """Test that plug-ins are loaded correctly."""
29 # pylint: disable=W0201
30 old_paths = plugins.DESKTOPCOUCH_PLUGIN_PATHS
31 plugins.DESKTOPCOUCH_PLUGIN_PATHS = [os.path.join(
32 os.path.dirname(__file__))]
33 self._imported = None
34 def _fake_import(name, *args, **kwargs):
35 """Fake import to check that we get imported."""
36 modname = name.replace('.test_', '.tests.test_')
37 if modname == __name__:
38 self._imported = modname
39 old_import = __import__
40 __builtins__['__import__'] = _fake_import
41 plugins.load_plugins()
42 __builtins__['__import__'] = old_import
43 plugins.DESKTOPCOUCH_PLUGIN_PATHS = old_paths
44 self.assertEqual(self._imported, __name__)
045
=== modified file 'desktopcouch/application/plugins/ubuntuone_pairing.py'
--- desktopcouch/application/plugins/ubuntuone_pairing.py 2011-01-03 13:31:57 +0000
+++ desktopcouch/application/plugins/ubuntuone_pairing.py 2011-01-05 15:54:30 +0000
@@ -88,14 +88,15 @@
88 follow_name_owner_changes=True)88 follow_name_owner_changes=True)
89 sso_backend = dbus.Interface(obj, dbus_interface=iface)89 sso_backend = dbus.Interface(obj, dbus_interface=iface)
90 sso_backend.find_credentials(APP_NAME, {})90 sso_backend.find_credentials(APP_NAME, {})
91
92 except ImportError:91 except ImportError:
93 logging.info('Ubuntu SSO is not available.')92 logging.info('Ubuntu SSO is not available.')
9493
9594
96def plugin_init():95def plugin_init():
97 """Set up the signal handler for pairing with Ubuntu One."""96 """Set up the signal handler for pairing with Ubuntu One."""
97 logging.info('Loaded Ubuntu One extension for desktopcouch.')
98 if sys.platform == 'win32':98 if sys.platform == 'win32':
99 logging.warning('Windows support for Ubuntu One is not yet ready.')99 logging.warning('Windows support for Ubuntu One is not yet ready.')
100 else:100 else:
101 listen_to_dbus()101 import gobject
102 gobject.idle_add(listen_to_dbus)
102103
=== modified file 'desktopcouch/application/service.py'
--- desktopcouch/application/service.py 2010-11-26 23:11:50 +0000
+++ desktopcouch/application/service.py 2011-01-05 15:54:30 +0000
@@ -35,7 +35,6 @@
35"""35"""
3636
37import os37import os
38import pkg_resources
39import time38import time
40import logging39import logging
41import logging.handlers40import logging.handlers
@@ -46,8 +45,7 @@
46from desktopcouch.application import stop_local_couchdb45from desktopcouch.application import stop_local_couchdb
47from desktopcouch.application.platform import (46from desktopcouch.application.platform import (
48 PortAdvertiser, find_pid, direct_access_find_port, CACHE_HOME)47 PortAdvertiser, find_pid, direct_access_find_port, CACHE_HOME)
4948from desktopcouch.application.plugins import load_plugins
50MAIN_START_EXTENSION_ENTRY_POINT = "desktopcouch.service.start"
5149
5250
53def set_up_logging(name):51def set_up_logging(name):
@@ -84,7 +82,7 @@
84 stop_couchdb=stop_local_couchdb.stop_couchdb,82 stop_couchdb=stop_local_couchdb.stop_couchdb,
85 replication_actions=replication,83 replication_actions=replication,
86 advertiser_factory=PortAdvertiser, set_logging=set_up_logging,84 advertiser_factory=PortAdvertiser, set_logging=set_up_logging,
87 resources=pkg_resources, fork=os.fork, nice=os.nice,85 fork=os.fork, nice=os.nice,
88 kill=os.kill, sleep=time.sleep):86 kill=os.kill, sleep=time.sleep):
89 self._mainloop = main_loop87 self._mainloop = main_loop
90 self._pid_finder = pid_finder88 self._pid_finder = pid_finder
@@ -94,7 +92,6 @@
94 self._replication = replication_actions92 self._replication = replication_actions
95 self._advertiser_factory = advertiser_factory93 self._advertiser_factory = advertiser_factory
96 self._logging = set_logging94 self._logging = set_logging
97 self._resources = resources
98 self._fork = fork95 self._fork = fork
99 self._nice = nice96 self._nice = nice
100 self._kill = kill97 self._kill = kill
@@ -118,11 +115,7 @@
118 self._advertiser_factory(self._mainloop.stop, self._ctx)115 self._advertiser_factory(self._mainloop.stop, self._ctx)
119 logging.debug("starting dbus main loop")116 logging.debug("starting dbus main loop")
120 try:117 try:
121 # we execute the extensions that have been registered118 load_plugins()
122 for entrypoint in self._resources.iter_entry_points(
123 group=MAIN_START_EXTENSION_ENTRY_POINT):
124 plugin = entrypoint.load()
125 plugin.execute()
126 self._mainloop.run()119 self._mainloop.run()
127 finally:120 finally:
128 logging.debug("ending dbus main loop")121 logging.debug("ending dbus main loop")
129122
=== modified file 'desktopcouch/application/tests/test_service.py'
--- desktopcouch/application/tests/test_service.py 2010-11-24 19:55:53 +0000
+++ desktopcouch/application/tests/test_service.py 2011-01-05 15:54:30 +0000
@@ -6,7 +6,7 @@
6from mocker import MockerTestCase, ANY6from mocker import MockerTestCase, ANY
77
8from desktopcouch.application.service import (8from desktopcouch.application.service import (
9 DesktopcouchService, MAIN_START_EXTENSION_ENTRY_POINT)9 DesktopcouchService)
1010
11logging.basicConfig(level=logging.ERROR)11logging.basicConfig(level=logging.ERROR)
1212
@@ -36,7 +36,6 @@
36 self._replication = self.mocker.mock()36 self._replication = self.mocker.mock()
37 self._advertiser = self.mocker.mock()37 self._advertiser = self.mocker.mock()
38 self._resources = self.mocker.mock()38 self._resources = self.mocker.mock()
39 self._start_extension = self.mocker.mock()
40 self._service = DesktopcouchService(self._mainloop,39 self._service = DesktopcouchService(self._mainloop,
41 pid_finder=self._pid_finder,40 pid_finder=self._pid_finder,
42 port_finder=self._port_finder,41 port_finder=self._port_finder,
@@ -48,8 +47,7 @@
48 fork=self._fork,47 fork=self._fork,
49 nice=self._nice,48 nice=self._nice,
50 kill=self._kill,49 kill=self._kill,
51 sleep=self._sleep,50 sleep=self._sleep)
52 resources=self._resources)
5351
54 def test_start_new_desktopcouch_no_extensions(self):52 def test_start_new_desktopcouch_no_extensions(self):
55 """Test that desktopcouch is started.53 """Test that desktopcouch is started.
@@ -70,9 +68,6 @@
70 self._mainloop.stop # pylint: disable=W010468 self._mainloop.stop # pylint: disable=W0104
71 self.mocker.result(ANY)69 self.mocker.result(ANY)
72 self._advertiser(ANY, self._ctx)70 self._advertiser(ANY, self._ctx)
73 self._resources.iter_entry_points(
74 group=MAIN_START_EXTENSION_ENTRY_POINT)
75 self.mocker.result([])
76 self._mainloop.run()71 self._mainloop.run()
77 self._stop_couchdb(ctx=self._ctx)72 self._stop_couchdb(ctx=self._ctx)
78 self._kill(234, signal.SIGTERM)73 self._kill(234, signal.SIGTERM)
@@ -100,12 +95,6 @@
100 self._mainloop.stop # pylint: disable=W010495 self._mainloop.stop # pylint: disable=W0104
101 self.mocker.result(ANY)96 self.mocker.result(ANY)
102 self._advertiser(ANY, self._ctx)97 self._advertiser(ANY, self._ctx)
103 self._resources.iter_entry_points(
104 group=MAIN_START_EXTENSION_ENTRY_POINT)
105 self.mocker.result([self._start_extension])
106 self._start_extension.load()
107 self.mocker.result(self._start_extension)
108 self._start_extension.execute()
109 self._mainloop.run()98 self._mainloop.run()
110 self._stop_couchdb(ctx=self._ctx)99 self._stop_couchdb(ctx=self._ctx)
111 self._kill(234, signal.SIGTERM)100 self._kill(234, signal.SIGTERM)

Subscribers

People subscribed via source and target branches