Merge lp:~alecu/ubuntuone-control-panel/backend-born into lp:~nataliabidart/ubuntuone-control-panel/trunk

Proposed by Alejandro J. Cura
Status: Merged
Merged at revision: 4
Proposed branch: lp:~alecu/ubuntuone-control-panel/backend-born
Merge into: lp:~nataliabidart/ubuntuone-control-panel/trunk
Diff against target: 555 lines (+494/-0)
10 files modified
integration/run-tests (+28/-0)
integration/test_dbus_client.py (+73/-0)
integration/test_dbus_service.py (+90/-0)
integration/test_webclient.py (+90/-0)
ubuntuone/controlpanel/__init__.py (+6/-0)
ubuntuone/controlpanel/backend.py (+22/-0)
ubuntuone/controlpanel/dbus_client.py (+54/-0)
ubuntuone/controlpanel/dbus_service.py (+74/-0)
ubuntuone/controlpanel/tests/test_backend.py (+31/-0)
ubuntuone/controlpanel/webclient.py (+26/-0)
To merge this branch: bzr merge lp:~alecu/ubuntuone-control-panel/backend-born
Reviewer Review Type Date Requested Status
Natalia Bidart Approve
Review via email: mp+36435@code.launchpad.net

Commit message

The foundations of the control panel backend

Description of the change

The foundations of the control panel backend

To post a comment you must log in.
9. By Alejandro J. Cura

fix pylint complaints

10. By Alejandro J. Cura

style fixes

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

Very nice!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'integration'
=== added file 'integration/__init__.py'
=== added file 'integration/run-tests'
--- integration/run-tests 1970-01-01 00:00:00 +0000
+++ integration/run-tests 2010-09-24 23:06:03 +0000
@@ -0,0 +1,28 @@
1#! /bin/bash
2#
3# Author: Natalia Bidart <natalia.bidart@gmail.com>
4# Author: Alejandro J. Cura <alecu@canonical.com>
5#
6# Copyright 2010 Canonical Ltd.
7#
8# This program is free software: you can redistribute it and/or modify it
9# under the terms of the GNU General Public License version 3, as published
10# by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranties of
14# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15# PURPOSE. See the GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program. If not, see <http://www.gnu.org/licenses/>.
19
20if [ $# -ne 0 ]; then
21 MODULE="$@"
22else
23 MODULE="integration"
24fi
25
26echo "Running test suite for ""$MODULE"
27PYTHONPATH=. `which xvfb-run` u1trial "$MODULE"
28rm -rf _trial_temp
029
=== added file 'integration/test_dbus_client.py'
--- integration/test_dbus_client.py 1970-01-01 00:00:00 +0000
+++ integration/test_dbus_client.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,73 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the control panel backend DBus service."""
20
21import dbus
22
23from twisted.internet import defer
24from twisted.trial import unittest
25
26from ubuntuone.controlpanel import dbus_service
27from ubuntuone.controlpanel import dbus_client
28from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH,
29 DBUS_PREFERENCES_IFACE)
30from ubuntuone.controlpanel.dbus_client import (DBUS_SSO_NAME, DBUS_SSO_PATH,
31 DBUS_SSO_IFACE)
32
33SAMPLE_CREDS = {
34 "token": "ABCDEF12345678",
35 "access_token": "DEADCAFE2010",
36}
37
38class MockDBusSSOClient(dbus.service.Object):
39 """A mock object that mimicks ussoc."""
40
41 @dbus.service.method(dbus_interface=DBUS_SSO_IFACE, in_signature="sssx")
42 def login_or_register_to_get_credentials(self, app_name, tcurl, help, wid):
43 """Get creds from the keyring, login/register if needed."""
44 self.CredentialsFound(app_name, SAMPLE_CREDS)
45
46 @dbus.service.signal(dbus_interface=DBUS_SSO_IFACE, signature="sa{ss}")
47 def CredentialsFound(self, app_name, credentials):
48 """Credentials were finally found."""
49
50class DBusClientTestCase(unittest.TestCase):
51 """test for the dbus client."""
52 timeout = 5
53
54 def setUp(self):
55 super(DBusClientTestCase, self).setUp()
56 dbus_service.init_mainloop()
57
58 def register_mockserver(self, bus_name, object_path, object_class):
59 """The mock service is registered on the DBus."""
60 session_bus = dbus.SessionBus()
61 name = session_bus.request_name(bus_name,
62 dbus.bus.NAME_FLAG_DO_NOT_QUEUE)
63 self.assertNotEqual(name, dbus.bus.REQUEST_NAME_REPLY_EXISTS)
64 bus_name = dbus.service.BusName(bus_name, bus=dbus.SessionBus())
65 object_class(object_path=DBUS_SSO_PATH, bus_name=bus_name)
66
67 @defer.inlineCallbacks
68 def test_get_credentials_ok(self):
69 """Test the success case for get_credentials."""
70 self.register_mockserver(DBUS_SSO_NAME, DBUS_SSO_PATH,
71 MockDBusSSOClient)
72 creds = yield dbus_client.get_credentials()
73 self.assertEqual(creds, SAMPLE_CREDS)
074
=== added file 'integration/test_dbus_service.py'
--- integration/test_dbus_service.py 1970-01-01 00:00:00 +0000
+++ integration/test_dbus_service.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,90 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the control panel backend DBus service."""
20
21import dbus
22
23from twisted.internet import defer
24from twisted.trial import unittest
25
26from ubuntuone.controlpanel import dbus_service
27from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH,
28 DBUS_PREFERENCES_IFACE)
29
30
31class DBusServiceTestCase(unittest.TestCase):
32 """Test for the DBus service."""
33 timeout = 5
34
35 def setUp(self):
36 """Initialize each test run."""
37 super(DBusServiceTestCase, self).setUp()
38 dbus_service.init_mainloop()
39
40 def test_register_service(self):
41 """The DBus service is successfully registered."""
42 ret = dbus_service.register_service()
43 self.assertTrue(ret)
44
45 def test_cant_register_twice(self):
46 """The DBus service can't register if it already did."""
47 ret = dbus_service.register_service()
48 self.assertTrue(ret)
49 ret = dbus_service.register_service()
50 self.assertFalse(ret)
51 test_cant_register_twice.skip = "Must run 2nd check in another process."
52
53 def test_dbus_busname_created(self):
54 """The DBus BusName is created."""
55 busname = dbus_service.get_busname()
56 self.assertEqual(busname.get_name(), DBUS_BUS_NAME)
57
58 def test_account_info_returned(self):
59 """The account info is successfully returned."""
60 dbus_service.publish_backend()
61
62 bus = dbus.SessionBus()
63 obj = bus.get_object(bus_name=DBUS_BUS_NAME,
64 object_path=DBUS_PREFERENCES_PATH,
65 follow_name_owner_changes=True)
66 self.iface_name = DBUS_PREFERENCES_IFACE
67 backend = dbus.Interface(object=obj,
68 dbus_interface=DBUS_PREFERENCES_IFACE)
69 d = defer.Deferred()
70
71 def got_signal(account_info):
72 """The correct signal was fired."""
73 self.assertIn("quota_used", account_info)
74 self.assertIn("quota_total", account_info)
75 self.assertIn("type", account_info)
76 self.assertIn("name", account_info)
77 self.assertIn("email", account_info)
78 d.callback("success")
79
80 def got_error(*a):
81 """Some error happened in the DBus call."""
82 d.errback(*a)
83
84 def ignore(*a):
85 """Do nothing with the returned value."""
86
87 backend.connect_to_signal("AccountInfoReady", got_signal)
88
89 backend.account_info(reply_handler=ignore, error_handler=got_error)
90 return d
091
=== added file 'integration/test_webclient.py'
--- integration/test_webclient.py 1970-01-01 00:00:00 +0000
+++ integration/test_webclient.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,90 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the control panel backend webservice client."""
20
21from twisted.application import internet, service
22from twisted.internet import defer
23from twisted.internet.defer import inlineCallbacks
24from twisted.internet.threads import deferToThread
25from twisted.trial import unittest
26from twisted.web import vhost, static, server, resource
27
28from ubuntuone.controlpanel import webclient
29
30SAMPLE_RESOURCE = "sample resource"
31
32
33class MockResource(resource.Resource):
34 """A simple web resource."""
35 isLeaf = True
36 contents = ""
37
38 def getChild(self, name, request):
39 """Get a given child resource."""
40 if name == '':
41 return self
42 return resource.Resource.getChild(self, name, request)
43
44 def render_GET(self, request):
45 """Make a bit of html out of these resource's content."""
46 return self.contents
47
48
49class MockWebService(object):
50 """A mock webservice for testing"""
51
52 def __init__(self):
53 """Start up this instance."""
54 root = MockResource()
55 root.contents = SAMPLE_RESOURCE
56 site = server.Site(root)
57 application = service.Application('web')
58 self.serviceCollection = service.IServiceCollection(application)
59 self.tcpserver = internet.TCPServer(0, site)
60 self.tcpserver.setServiceParent(self.serviceCollection)
61 self.serviceCollection.startService()
62
63 def get_url(self):
64 """Build the url for this mock server."""
65 portNum = self.tcpserver._port.getHost().port
66 return "http://localhost:%d/" % portNum
67
68 def stop(self):
69 """Shut it down."""
70 self.serviceCollection.stopService()
71
72
73class WebClientTestCase(unittest.TestCase):
74 """Test for the webservice client."""
75 timeout = 5
76
77 def setUp(self):
78 super(WebClientTestCase, self).setUp()
79 self.ws = MockWebService()
80
81 def tearDown(self):
82 super(WebClientTestCase, self).tearDown()
83 self.ws.stop()
84
85 @inlineCallbacks
86 def test_connect(self):
87 """Connect to the mock webservice."""
88 webclient.BASE_URL = self.ws.get_url()
89 ret = yield deferToThread(webclient.getinfo)
90 self.assertEqual(ret, SAMPLE_RESOURCE)
091
=== modified file 'ubuntuone/controlpanel/__init__.py'
--- ubuntuone/controlpanel/__init__.py 2010-09-15 21:43:48 +0000
+++ ubuntuone/controlpanel/__init__.py 2010-09-24 23:06:03 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
22
3# Authors: Natalia B Bidart <natalia.bidart@canonical.com>3# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
4# Authors: Alejandro J. Cura <alecu@canonical.com>
4#5#
5# Copyright 2010 Canonical Ltd.6# Copyright 2010 Canonical Ltd.
6#7#
@@ -22,3 +23,8 @@
22their Ubuntu One subscription and preferences.23their Ubuntu One subscription and preferences.
2324
24"""25"""
26
27# constants
28DBUS_BUS_NAME = "com.ubuntuone.controlpanel"
29DBUS_PREFERENCES_PATH = "/preferences"
30DBUS_PREFERENCES_IFACE = "com.ubuntuone.controlpanel.Preferences"
2531
=== added file 'ubuntuone/controlpanel/backend.py'
--- ubuntuone/controlpanel/backend.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/controlpanel/backend.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,22 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""A backend for the Ubuntu One Control Panel."""
20
21class ControlBackend(object):
22 """A backend."""
023
=== added file 'ubuntuone/controlpanel/dbus_client.py'
--- ubuntuone/controlpanel/dbus_client.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/controlpanel/dbus_client.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,54 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Client to use other DBus services."""
20
21import dbus.service
22
23from twisted.internet import defer
24
25DBUS_SSO_NAME = "com.ubuntu.sso"
26DBUS_SSO_PATH = "/credentials"
27DBUS_SSO_IFACE = "com.ubuntu.sso.ApplicationCredentials"
28
29
30def get_credentials():
31 """Get the credentials from the ubuntu-sso-client."""
32 bus = dbus.SessionBus()
33 obj = bus.get_object(bus_name=DBUS_SSO_NAME,
34 object_path=DBUS_SSO_PATH,
35 follow_name_owner_changes=True)
36 proxy = dbus.Interface(object=obj, dbus_interface=DBUS_SSO_IFACE)
37 d = defer.Deferred()
38
39 def ignore_return(*a):
40 """The return value of the call to the proxy can be safely ignored."""
41
42 def flag_error(*a):
43 """Make a twisted error from the error returned by the DBus call."""
44 d.errback(*a)
45
46 def found_credentials(app_name, creds):
47 """Credentials have been found."""
48 d.callback(creds)
49
50 proxy.connect_to_signal("CredentialsFound", found_credentials)
51 proxy.login_or_register_to_get_credentials("app", "tcurl", "help", 0,
52 reply_handler=ignore_return,
53 error_handler=flag_error)
54 return d
055
=== added file 'ubuntuone/controlpanel/dbus_service.py'
--- ubuntuone/controlpanel/dbus_service.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/controlpanel/dbus_service.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,74 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Export the control backend thru DBus."""
20
21import dbus.service
22
23from dbus.mainloop.glib import DBusGMainLoop
24from dbus.service import method, signal
25
26from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH,
27 DBUS_PREFERENCES_IFACE)
28
29# XXX: should get this info from the web service
30SAMPLE_DATA = {
31 "quota_used": "12345",
32 "quota_total": "54321",
33 "type": "paying customer",
34 "name": "john carlos",
35 "email": "john@carlos.com",
36}
37
38class ControlPanelBackend(dbus.service.Object):
39 """Export the Control Panel backend thru DBus."""
40 # pylint: disable=C0103
41
42 @method(dbus_interface=DBUS_PREFERENCES_IFACE, in_signature="")
43 def account_info(self):
44 """Find out the account info for the current logged in user."""
45 self.AccountInfoReady(SAMPLE_DATA)
46
47 @signal(dbus_interface=DBUS_PREFERENCES_IFACE, signature="a{ss}")
48 def AccountInfoReady(self, info):
49 """The info for the current user is available now."""
50
51def init_mainloop():
52 """Start the DBus mainloop."""
53 DBusGMainLoop(set_as_default=True)
54
55def register_service():
56 """Try to register DBus service for making sure we run only one instance.
57
58 Return True if succesfully registered, False if already running.
59 """
60 session_bus = dbus.SessionBus()
61 name = session_bus.request_name(DBUS_BUS_NAME,
62 dbus.bus.NAME_FLAG_DO_NOT_QUEUE)
63 return name != dbus.bus.REQUEST_NAME_REPLY_EXISTS
64
65
66def get_busname():
67 """Build the DBus BusName."""
68 return dbus.service.BusName(DBUS_BUS_NAME, bus=dbus.SessionBus())
69
70
71def publish_backend():
72 """Publish the backend on the DBus."""
73 ControlPanelBackend(object_path=DBUS_PREFERENCES_PATH,
74 bus_name=get_busname())
075
=== added file 'ubuntuone/controlpanel/tests/test_backend.py'
--- ubuntuone/controlpanel/tests/test_backend.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/controlpanel/tests/test_backend.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,31 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the control panel backend."""
20
21from twisted.trial.unittest import TestCase
22
23from ubuntuone.controlpanel import backend
24
25class BackendBasicTestCase(TestCase):
26 """Simple tests for the backend."""
27
28 def test_backend_creation(self):
29 """The backend instance is created."""
30 be = backend.ControlBackend()
31 self.assertNotEqual(be, None)
032
=== added file 'ubuntuone/controlpanel/webclient.py'
--- ubuntuone/controlpanel/webclient.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/controlpanel/webclient.py 2010-09-24 23:06:03 +0000
@@ -0,0 +1,26 @@
1# Authors: Alejandro J. Cura <alecu@canonical.com>
2#
3# Copyright 2010 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16
17"""The control panel backend webservice client."""
18
19import urllib
20
21BASE_URL = "https://one.ubuntu.com/api/1.0/"
22
23def getinfo():
24 """Get the info from the url."""
25 f = urllib.urlopen(BASE_URL + "devices/")
26 return f.read()

Subscribers

People subscribed via source and target branches