Merge lp:~salgado/offspring/sidebars into lp:~linaro-automation/offspring/private-builds

Proposed by Guilherme Salgado
Status: Merged
Approved by: James Tunnicliffe
Approved revision: no longer in the source branch.
Merged at revision: 68
Proposed branch: lp:~salgado/offspring/sidebars
Merge into: lp:~linaro-automation/offspring/private-builds
Prerequisite: lp:~salgado/offspring/builder-details
Diff against target: 317 lines (+163/-19)
8 files modified
lib/offspring/web/queuemanager/models.py (+7/-6)
lib/offspring/web/queuemanager/templatetags/lexbuilder_sidebars.py (+23/-6)
lib/offspring/web/queuemanager/tests/factory.py (+2/-2)
lib/offspring/web/queuemanager/tests/test_models.py (+25/-0)
lib/offspring/web/queuemanager/tests/test_views.py (+93/-0)
lib/offspring/web/templates/base.html (+3/-3)
lib/offspring/web/templates/queuemanager/sidebars/build_farm.html (+5/-1)
lib/offspring/web/templates/queuemanager/sidebars/queued_builds.html (+5/-1)
To merge this branch: bzr merge lp:~salgado/offspring/sidebars
Reviewer Review Type Date Requested Status
James Tunnicliffe (community) Approve
Review via email: mp+79834@code.launchpad.net

Description of the change

Update the build failures sidebar to skip private builds the user is not allowed to see, and the queued-builds and build-farm sidebars to simply state it's a private build (without any other information) when the user is not allowed to see them

To post a comment you must log in.
Revision history for this message
James Tunnicliffe (dooferlad) wrote :

Nice.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/offspring/web/queuemanager/models.py'
2--- lib/offspring/web/queuemanager/models.py 2011-10-19 14:51:51 +0000
3+++ lib/offspring/web/queuemanager/models.py 2011-10-19 15:12:46 +0000
4@@ -429,17 +429,18 @@
5 else:
6 return None
7
8- def recentBuildFailures(limit=5):
9+ def recentBuildFailures(user, limit=5):
10 #XXX: Should be method of custom model manager.
11 threshold = datetime.now() - timedelta(weeks=2)
12- r = BuildResult.objects.select_related(
13- 'project').filter(finished_at__gte = threshold).filter(
14- result = ProjectBuildStates.FAILED).order_by(
15+ builds = BuildResult.all_objects.accessible_by_user(user)
16+ query = models.Q(
17+ finished_at__gte=threshold, result=ProjectBuildStates.FAILED)
18+ builds = builds.select_related('project').filter(query).order_by(
19 "finished_at").reverse()
20 if limit is None:
21- return r
22+ return builds
23 else:
24- return r[:limit]
25+ return builds[:limit]
26 recentBuildFailures = staticmethod(recentBuildFailures)
27
28
29
30=== modified file 'lib/offspring/web/queuemanager/templatetags/lexbuilder_sidebars.py'
31--- lib/offspring/web/queuemanager/templatetags/lexbuilder_sidebars.py 2011-01-22 05:41:52 +0000
32+++ lib/offspring/web/queuemanager/templatetags/lexbuilder_sidebars.py 2011-10-19 15:12:46 +0000
33@@ -11,14 +11,31 @@
34
35 register = template.Library()
36
37-def show_sidebar_failedbuilds():
38- return { 'recent_failures' : BuildResult.recentBuildFailures() }
39+def show_sidebar_failedbuilds(user):
40+ return {'recent_failures': BuildResult.recentBuildFailures(user)}
41 register.inclusion_tag('queuemanager/sidebars/failed_builds.html')(show_sidebar_failedbuilds)
42
43-def show_sidebar_queuedbuilds():
44- return { 'pending_builds' : BuildRequest.objects.select_related('project', 'requestor').order_by("score").reverse()[:5] }
45+def show_sidebar_queuedbuilds(user):
46+ # Instead of filtering out the private builds the user is not allowed to
47+ # see we state in the UI that there's a private build queued, but don't
48+ # include any information about its project.
49+ builds = BuildRequest.all_objects.select_related(
50+ 'project', 'requestor').order_by("score").reverse()[:5]
51+ builds_to_show = {}
52+ for build in builds:
53+ builds_to_show[build] = build.is_visible_to(user)
54+ return {'pending_builds': builds_to_show}
55 register.inclusion_tag('queuemanager/sidebars/queued_builds.html')(show_sidebar_queuedbuilds)
56
57-def show_sidebar_buildfarm():
58- return { 'lexbuilders' : Lexbuilder.objects.exclude(is_active=False).select_related('current_job__project').order_by("name") }
59+def show_sidebar_buildfarm(user):
60+ # Instead of filtering out the builders that are working on private
61+ # projects the user is not allowed to see we state in the UI that it's
62+ # working on a private project, without including any information about
63+ # the project itself.
64+ builders = Lexbuilder.all_objects.exclude(is_active=False).select_related(
65+ 'current_job__project').order_by("name")
66+ builders_to_show = {}
67+ for builder in builders:
68+ builders_to_show[builder] = builder.is_visible_to(user)
69+ return {'lexbuilders': builders_to_show}
70 register.inclusion_tag('queuemanager/sidebars/build_farm.html')(show_sidebar_buildfarm)
71
72=== modified file 'lib/offspring/web/queuemanager/tests/factory.py'
73--- lib/offspring/web/queuemanager/tests/factory.py 2011-10-11 18:54:36 +0000
74+++ lib/offspring/web/queuemanager/tests/factory.py 2011-10-19 15:12:46 +0000
75@@ -67,14 +67,14 @@
76 return group
77
78 def makeBuildResult(self, project=None, name=None, result=None,
79- builder=None):
80+ builder=None, finished_at=None):
81 if name is None:
82 name = self.getUniqueString()
83 if project is None:
84 project = self.makeProject()
85 project.save()
86 result = BuildResult(name=name, project=project, result=result,
87- builder=builder)
88+ builder=builder, finished_at=finished_at)
89 result.save()
90 return result
91
92
93=== modified file 'lib/offspring/web/queuemanager/tests/test_models.py'
94--- lib/offspring/web/queuemanager/tests/test_models.py 2011-09-29 18:14:35 +0000
95+++ lib/offspring/web/queuemanager/tests/test_models.py 2011-10-19 15:12:46 +0000
96@@ -1,8 +1,10 @@
97+from datetime import datetime
98 from operator import attrgetter
99
100 from django.contrib.auth.models import AnonymousUser
101 from django.test import TestCase
102
103+from offspring.enums import ProjectBuildStates
104 from offspring.web.queuemanager.models import (
105 BuildRequest,
106 BuildResult,
107@@ -204,6 +206,29 @@
108 model = BuildResult
109 factoryMethod = factory.makeBuildResult
110
111+ def test_recentBuildFailures_public_project(self):
112+ project = factory.makeProject(is_private=False)
113+ build = self.makeFailedBuild(project)
114+ self.assertEqual(
115+ [build], list(build.recentBuildFailures(AnonymousUser())))
116+
117+ def test_recentBuildFailures_private_project_visible_to_user(self):
118+ project = factory.makeProject(is_private=True)
119+ build = self.makeFailedBuild(project)
120+ self.assertEqual(
121+ [build], list(build.recentBuildFailures(project.owner)))
122+
123+ def test_recentBuildFailures_private_project_invisible_to_user(self):
124+ project = factory.makeProject(is_private=True)
125+ build = self.makeFailedBuild(project)
126+ self.assertEqual(
127+ [], list(build.recentBuildFailures(factory.makeUser())))
128+
129+ def makeFailedBuild(self, project):
130+ return factory.makeBuildResult(
131+ project, result=ProjectBuildStates.FAILED,
132+ finished_at=datetime.now())
133+
134
135 class BuildRequestTests(
136 TestCase, ReleaseOrLexbuilderOrBuildResultOrBuildRequestTestsMixin):
137
138=== modified file 'lib/offspring/web/queuemanager/tests/test_views.py'
139--- lib/offspring/web/queuemanager/tests/test_views.py 2011-10-19 15:12:46 +0000
140+++ lib/offspring/web/queuemanager/tests/test_views.py 2011-10-19 15:12:46 +0000
141@@ -1,6 +1,12 @@
142+from datetime import datetime
143+
144 from django.core.urlresolvers import reverse
145 from django.contrib.auth.models import AnonymousUser
146 from django.http import Http404
147+from django.template import (
148+ Context,
149+ Template,
150+ )
151 from django.test import TestCase
152
153 from offspring.enums import ProjectBuildStates
154@@ -388,6 +394,93 @@
155 msg_prefix=response.content)
156
157
158+class FailedBuildsSidebarTests(TestCase):
159+
160+ template = Template(
161+ "{% load lexbuilder_sidebars %}"
162+ "{% show_sidebar_failedbuilds user %}")
163+
164+ def test_public_builds(self):
165+ build = self.makeBuildResult(is_private=False)
166+ out = self.template.render(Context({'user': AnonymousUser()}))
167+ self.assertTrue(build.name in out, out)
168+
169+ def test_private_builds_are_shown_if_user_has_rights(self):
170+ build = self.makeBuildResult(is_private=True)
171+ out = self.template.render(Context({'user': build.project.owner}))
172+ self.assertTrue(build.name in out, out)
173+
174+ def test_private_builds_are_not_shown_if_user_has_no_rights(self):
175+ build = self.makeBuildResult(is_private=True)
176+ out = self.template.render(Context({'user': factory.makeUser()}))
177+ self.assertTrue(build.name not in out, out)
178+
179+ def makeBuildResult(self, is_private):
180+ project = factory.makeProject(is_private=is_private)
181+ return factory.makeBuildResult(
182+ project=project, result=ProjectBuildStates.FAILED,
183+ finished_at=datetime.now())
184+
185+
186+class QueuedBuildsSidebarTests(TestCase):
187+
188+ template = Template(
189+ "{% load lexbuilder_sidebars %}"
190+ "{% show_sidebar_queuedbuilds user %}")
191+
192+ def test_public_builds(self):
193+ build = self.makeBuildRequest(is_private=False)
194+ out = self.template.render(Context({'user': AnonymousUser()}))
195+ self.assertTrue(str(build) in out, out)
196+
197+ def test_private_builds_are_shown_if_user_has_rights(self):
198+ build = self.makeBuildRequest(is_private=True)
199+ out = self.template.render(Context({'user': build.project.owner}))
200+ self.assertTrue(str(build) in out, out)
201+
202+ def test_private_builds_are_not_shown_if_user_has_no_rights(self):
203+ build = self.makeBuildRequest(is_private=True)
204+ out = self.template.render(Context({'user': factory.makeUser()}))
205+ self.assertTrue(str(build) not in out, out)
206+ self.assertTrue('Private build' in out, out)
207+
208+ def makeBuildRequest(self, is_private):
209+ project = factory.makeProject(is_private=is_private)
210+ return factory.makeBuildRequest(project=project)
211+
212+
213+class BuildFarmSidebarTests(TestCase):
214+
215+ template = Template(
216+ "{% load lexbuilder_sidebars %}"
217+ "{% show_sidebar_buildfarm user %}")
218+
219+ def test_public_builds(self):
220+ builder = self.makeBuilderWithCurrentJob(is_private=False)
221+ out = self.template.render(Context({'user': AnonymousUser()}))
222+ self.assertTrue(builder.current_job.name in out, out)
223+
224+ def test_private_builds_are_shown_if_user_has_rights(self):
225+ builder = self.makeBuilderWithCurrentJob(is_private=True)
226+ out = self.template.render(
227+ Context({'user': builder.current_job.project.owner}))
228+ self.assertTrue(builder.current_job.name in out, out)
229+
230+ def test_private_builds_are_not_shown_if_user_has_no_rights(self):
231+ builder = self.makeBuilderWithCurrentJob(is_private=True)
232+ out = self.template.render(Context({'user': factory.makeUser()}))
233+ self.assertTrue(builder.current_job.name not in out, out)
234+ self.assertTrue('Private build' in out, out)
235+
236+ def makeBuilderWithCurrentJob(self, is_private):
237+ project = factory.makeProject(is_private=is_private)
238+ job = factory.makeBuildResult(project=project)
239+ builder = factory.makeLexbuilder(current_job=job)
240+ builder.current_state = 'BUILDING'
241+ builder.save()
242+ return builder
243+
244+
245 def make_user_and_login(client):
246 user = factory.makeUser()
247 return client.login(username=user.username, password=user.username)
248
249=== modified file 'lib/offspring/web/templates/base.html'
250--- lib/offspring/web/templates/base.html 2011-10-10 20:12:47 +0000
251+++ lib/offspring/web/templates/base.html 2011-10-19 15:12:46 +0000
252@@ -112,17 +112,17 @@
253 <ul id="sidebarul">
254 {% block sidebar-failedbuilds %}
255 <li>
256- {% show_sidebar_failedbuilds %}
257+ {% show_sidebar_failedbuilds user %}
258 </li>
259 {% endblock %}
260 {% block sidebar-queuedbuilds %}
261 <li>
262- {% show_sidebar_queuedbuilds %}
263+ {% show_sidebar_queuedbuilds user %}
264 </li>
265 {% endblock %}
266 {% block sidebar-buildfarm %}
267 <li class="gray">
268- {% show_sidebar_buildfarm %}
269+ {% show_sidebar_buildfarm user %}
270 </li>
271 {% endblock %}
272 </ul>
273
274=== modified file 'lib/offspring/web/templates/queuemanager/sidebars/build_farm.html'
275--- lib/offspring/web/templates/queuemanager/sidebars/build_farm.html 2010-11-29 08:27:24 +0000
276+++ lib/offspring/web/templates/queuemanager/sidebars/build_farm.html 2011-10-19 15:12:46 +0000
277@@ -3,17 +3,21 @@
278 <h2>Build Farm</h2>
279 <ul class="builder_status">
280 {% if lexbuilders %}
281- {% for builder in lexbuilders %}
282+ {% for builder, should_show_build in lexbuilders.items %}
283 <li class="{{ builder.status }}">
284 <a href="{% url builder_details builder %}" title="View builder details">{{ builder }}</a>:
285 {% ifequal builder.current_state "BUILDING" %}
286 <p>
287+ {% if should_show_build %}
288 <a title="View project details" href="{% url offspring.web.queuemanager.views.project_details builder.current_build_projectname %}">
289 {{builder.current_build_projectname}}
290 </a>
291 <a title="View build log in new window" target="_blank" href="{{ builder.current_build_projectname|link_results:builder.current_build_buildname }}/build-log.txt">
292 ({{builder.current_build_buildname|default:"..."}})
293 </a>
294+ {% else %}
295+ Private build
296+ {% endif %}
297 </p>
298 {% else %}
299 {{ builder.status }}
300
301=== modified file 'lib/offspring/web/templates/queuemanager/sidebars/queued_builds.html'
302--- lib/offspring/web/templates/queuemanager/sidebars/queued_builds.html 2010-11-29 08:27:24 +0000
303+++ lib/offspring/web/templates/queuemanager/sidebars/queued_builds.html 2011-10-19 15:12:46 +0000
304@@ -1,8 +1,12 @@
305 <h2 class="blue">Pending Builds</h2>
306 {% if pending_builds %}
307 <ul class="builds_pending">
308- {% for build_request in pending_builds %}
309+ {% for build_request, should_show in pending_builds.items %}
310+ {% if should_show %}
311 <li title="Build Pending"> <a href="{% url offspring.web.queuemanager.views.project_details build_request.project.name %}" title="{{ build_request }}{% if user.is_staff %} Score: {{ build_request.score }} {% endif %}">{{ build_request.project }}</a></li>
312+ {% else %}
313+ <li title="Build Pending">Private build</li>
314+ {% endif %}
315 {% endfor %}
316 {% else %}
317 <ul>

Subscribers

People subscribed via source and target branches