Merge lp:~wgrant/launchpad/bug-766742 into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 12907
Proposed branch: lp:~wgrant/launchpad/bug-766742
Merge into: lp:launchpad
Diff against target: 99 lines (+47/-3)
2 files modified
lib/canonical/launchpad/webapp/login.py (+17/-3)
lib/canonical/launchpad/webapp/tests/test_login.py (+30/-0)
To merge this branch: bzr merge lp:~wgrant/launchpad/bug-766742
Reviewer Review Type Date Requested Status
j.c.sackett (community) Approve
Review via email: mp+58643@code.launchpad.net

Commit message

[r=jcsackett][bug=766742] OpenID actions on +login and +openid-callback now appear in the request timeline.

Description of the change

RootObject:+login has been frequently timing out lately, with a 10s gap between SQL statements that probably surround an OpenID HTTP request to SSO. This branch logs the start and end of the OpenID operations at both ends of authentication, so we can get a better idea of where the slowness lies.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

you need some try:finally's around.

I think you need "" rather than None for the detail, for oops-tools to be happy.

Revision history for this message
j.c.sackett (jcsackett) wrote :

Looks fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/webapp/login.py'
2--- lib/canonical/launchpad/webapp/login.py 2010-12-16 15:42:22 +0000
3+++ lib/canonical/launchpad/webapp/login.py 2011-04-21 10:03:59 +0000
4@@ -62,6 +62,7 @@
5 PersonCreationRationale,
6 )
7 from lp.services.propertycache import cachedproperty
8+from lp.services.timeline.requesttimeline import get_request_timeline
9
10
11 class UnauthorizedView(SystemErrorView):
12@@ -195,8 +196,16 @@
13 allowUnauthenticatedSession(self.request)
14 consumer = self._getConsumer()
15 openid_vhost = config.launchpad.openid_provider_vhost
16- self.openid_request = consumer.begin(
17- allvhosts.configs[openid_vhost].rooturl)
18+
19+ timeline_action = get_request_timeline(self.request).start(
20+ "openid-association-begin",
21+ allvhosts.configs[openid_vhost].rooturl,
22+ allow_nested=True)
23+ try:
24+ self.openid_request = consumer.begin(
25+ allvhosts.configs[openid_vhost].rooturl)
26+ finally:
27+ timeline_action.finish()
28 self.openid_request.addExtension(
29 sreg.SRegRequest(optional=['email', 'fullname']))
30
31@@ -283,7 +292,12 @@
32 params = self._gather_params(self.request)
33 requested_url = self._get_requested_url(self.request)
34 consumer = self._getConsumer()
35- self.openid_response = consumer.complete(params, requested_url)
36+ timeline_action = get_request_timeline(self.request).start(
37+ "openid-association-complete", '', allow_nested=True)
38+ try:
39+ self.openid_response = consumer.complete(params, requested_url)
40+ finally:
41+ timeline_action.finish()
42
43 def login(self, account):
44 loginsource = getUtility(IPlacelessLoginSource)
45
46=== modified file 'lib/canonical/launchpad/webapp/tests/test_login.py'
47--- lib/canonical/launchpad/webapp/tests/test_login.py 2010-12-08 17:22:23 +0000
48+++ lib/canonical/launchpad/webapp/tests/test_login.py 2011-04-21 10:03:59 +0000
49@@ -62,6 +62,7 @@
50 )
51 from lp.registry.interfaces.person import IPerson
52 from lp.services.openid.model.openididentifier import OpenIdIdentifier
53+from lp.services.timeline.requesttimeline import get_request_timeline
54 from lp.testing import (
55 logout,
56 TestCaseWithFactory,
57@@ -468,6 +469,19 @@
58 AssertionError,
59 getUtility(IAccountSet).getByOpenIDIdentifier, u'foo')
60
61+ def test_logs_to_timeline(self):
62+ # Completing an OpenID association *can* make an HTTP request to the
63+ # OP, so it's a potentially long action. It is logged to the
64+ # request timeline.
65+ account = self.factory.makeAccount('Test account')
66+ with SRegResponse_fromSuccessResponse_stubbed():
67+ view, html = self._createViewWithResponse(account)
68+ start, stop = get_request_timeline(view.request).actions[-2:]
69+ self.assertEqual(start.category, 'openid-association-complete-start')
70+ self.assertEqual(start.detail, '')
71+ self.assertEqual(stop.category, 'openid-association-complete-stop')
72+ self.assertEqual(stop.detail, '')
73+
74 def assertLastWriteIsSet(self, request):
75 last_write = ISession(request)['lp.dbpolicy']['last_write']
76 self.assertTrue(datetime.utcnow() - last_write < timedelta(minutes=1))
77@@ -640,6 +654,22 @@
78 self.assertEquals(['email', 'fullname'],
79 sorted(sreg_extension.allRequestedFields()))
80
81+ def test_logs_to_timeline(self):
82+ # Beginning an OpenID association makes an HTTP request to the
83+ # OP, so it's a potentially long action. It is logged to the
84+ # request timeline.
85+ request = LaunchpadTestRequest()
86+ # This is a hack to make the request.getURL(1) call issued by the view
87+ # not raise an IndexError.
88+ request._app_names = ['foo']
89+ view = StubbedOpenIDLogin(object(), request)
90+ view()
91+ start, stop = get_request_timeline(request).actions[-2:]
92+ self.assertEqual(start.category, 'openid-association-begin-start')
93+ self.assertEqual(start.detail, 'http://testopenid.dev/')
94+ self.assertEqual(stop.category, 'openid-association-begin-stop')
95+ self.assertEqual(stop.detail, 'http://testopenid.dev/')
96+
97
98 class TestOpenIDRealm(TestCaseWithFactory):
99 # The realm (aka trust_root) specified by the RP is "designed to give the