Merge lp:~cjwatson/launchpad/person-api-cache-logo-mugshot into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 19032
Proposed branch: lp:~cjwatson/launchpad/person-api-cache-logo-mugshot
Merge into: lp:launchpad
Diff against target: 118 lines (+40/-28)
2 files modified
lib/lp/registry/model/person.py (+9/-1)
lib/lp/registry/tests/test_person.py (+31/-27)
To merge this branch: bzr merge lp:~cjwatson/launchpad/person-api-cache-logo-mugshot
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+371597@code.launchpad.net

Commit message

Cache logos and mugshots for team API queries.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)
Revision history for this message
Colin Watson (cjwatson) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/model/person.py'
2--- lib/lp/registry/model/person.py 2019-08-07 00:04:58 +0000
3+++ lib/lp/registry/model/person.py 2019-08-23 10:41:43 +0000
4@@ -4030,9 +4030,17 @@
5 columns.extend(valid_stuff["tables"])
6 decorators.extend(valid_stuff["decorators"])
7 if need_icon:
8- IconAlias = ClassAlias(LibraryFileAlias, "LibraryFileAlias")
9+ IconAlias = ClassAlias(LibraryFileAlias, "IconAlias")
10 origin.append(LeftJoin(IconAlias, Person.icon == IconAlias.id))
11 columns.append(IconAlias)
12+ if need_api:
13+ LogoAlias = ClassAlias(LibraryFileAlias, "LogoAlias")
14+ MugshotAlias = ClassAlias(LibraryFileAlias, "MugshotAlias")
15+ origin.extend([
16+ LeftJoin(LogoAlias, Person.logo == LogoAlias.id),
17+ LeftJoin(MugshotAlias, Person.mugshot == MugshotAlias.id),
18+ ])
19+ columns.extend([LogoAlias, MugshotAlias])
20 if len(columns) == 1:
21 column = columns[0]
22 # Return a simple ResultSet
23
24=== modified file 'lib/lp/registry/tests/test_person.py'
25--- lib/lp/registry/tests/test_person.py 2018-04-22 23:30:37 +0000
26+++ lib/lp/registry/tests/test_person.py 2019-08-23 10:41:43 +0000
27@@ -1,4 +1,4 @@
28-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
29+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
30 # GNU Affero General Public License version 3 (see the file LICENSE).
31
32 __metaclass__ = type
33@@ -13,10 +13,7 @@
34 import pytz
35 from storm.locals import Desc
36 from storm.store import Store
37-from testtools.matchers import (
38- Equals,
39- LessThan,
40- )
41+from testtools.matchers import Equals
42 from zope.component import getUtility
43 from zope.interface import providedBy
44 from zope.security.interfaces import Unauthorized
45@@ -72,10 +69,11 @@
46 celebrity_logged_in,
47 launchpadlib_for,
48 login,
49+ login_admin,
50 login_person,
51 logout,
52 person_logged_in,
53- RequestTimelineCollector,
54+ record_two_runs,
55 StormStatementRecorder,
56 TestCaseWithFactory,
57 )
58@@ -1258,33 +1256,39 @@
59 ['cc', 'bb', 'aa', 'dd', 'ee'], names)
60
61
62-class TestAPIPartipication(TestCaseWithFactory):
63+class TestAPIParticipation(TestCaseWithFactory):
64
65 layer = DatabaseFunctionalLayer
66
67- def test_participation_query_limit(self):
68- # A team with 3 members should only query once for all their
69- # attributes.
70+ def test_participation_query_count(self):
71+ # The query count of team.participants is constant in the number of
72+ # members.
73 team = self.factory.makeTeam()
74- with person_logged_in(team.teamowner):
75- team.addMember(self.factory.makePerson(), team.teamowner)
76- team.addMember(self.factory.makePerson(), team.teamowner)
77- team.addMember(self.factory.makePerson(), team.teamowner)
78+ teamowner = team.teamowner
79 webservice = LaunchpadWebServiceCaller()
80- collector = RequestTimelineCollector()
81- collector.register()
82- self.addCleanup(collector.unregister)
83 url = "/~%s/participants" % team.name
84- logout()
85- response = webservice.get(url,
86- headers={'User-Agent': 'AnonNeedsThis'})
87- self.assertEqual(response.status, 200,
88- "Got %d for url %r with response %r" % (
89- response.status, url, response.body))
90- # XXX: This number should really be 12, but see
91- # https://bugs.launchpad.net/storm/+bug/619017 which is adding 3
92- # queries to the test.
93- self.assertThat(collector, HasQueryCount(LessThan(16)))
94+
95+ def make_team_member():
96+ person = self.factory.makePerson()
97+ person.logo = self.factory.makeLibraryFileAlias(
98+ content_type='image/png', db_only=True)
99+ person.mugshot = self.factory.makeLibraryFileAlias(
100+ content_type='image/png', db_only=True)
101+ team.addMember(person, teamowner)
102+
103+ def get_participants():
104+ logout()
105+ response = webservice.get(
106+ url, headers={'User-Agent': 'AnonNeedsThis'})
107+ self.assertEqual(
108+ 200, response.status,
109+ "Got %d for url %r with response %r" % (
110+ response.status, url, response.body))
111+
112+ recorder1, recorder2 = record_two_runs(
113+ get_participants, make_team_member, 1, 2, login_method=login_admin,
114+ record_request=True)
115+ self.assertThat(recorder2, HasQueryCount.byEquality(recorder1))
116
117
118 class TestGetRecipients(TestCaseWithFactory):