Merge lp:~rockstar/launchpad/lil-recipe-bugs into lp:launchpad

Proposed by Paul Hummer
Status: Merged
Approved by: Paul Hummer
Approved revision: no longer in the source branch.
Merged at revision: 11871
Proposed branch: lp:~rockstar/launchpad/lil-recipe-bugs
Merge into: lp:launchpad
Prerequisite: lp:~thumper/launchpad/recipe-help
Diff against target: 339 lines (+257/-3) (has conflicts)
5 files modified
lib/lp/blueprints/interfaces/specification.py (+9/-0)
lib/lp/bugs/tests/test_bugtask_search.py (+205/-0)
lib/lp/code/browser/sourcepackagerecipe.py (+8/-2)
lib/lp/code/help/related-recipes.html (+33/-0)
lib/lp/code/interfaces/sourcepackagerecipe.py (+2/-1)
Text conflict in lib/lp/blueprints/interfaces/specification.py
Text conflict in lib/lp/bugs/tests/test_bugtask_search.py
Text conflict in lib/lp/code/help/related-recipes.html
To merge this branch: bzr merge lp:~rockstar/launchpad/lil-recipe-bugs
Reviewer Review Type Date Requested Status
Deryck Hodge (community) code Approve
Review via email: mp+40143@code.launchpad.net

Commit message

Fix many recipe bugs.

Description of the change

This branch fixes a couple of little recipe bugs that were marked high. These changes are the kind that don't really have tests to go along with them.

To post a comment you must log in.
Revision history for this message
Deryck Hodge (deryck) wrote :

<deryck> rockstar, "this the archive where the package" should be "this *is* the archive where the package" ?
<rockstar> deryck, fixeded.
<deryck> rockstar, r=me then
<rockstar> This is why we get reviews, even for little branches...

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/blueprints/interfaces/specification.py'
2--- lib/lp/blueprints/interfaces/specification.py 2010-11-04 03:34:54 +0000
3+++ lib/lp/blueprints/interfaces/specification.py 2010-11-05 17:57:18 +0000
4@@ -37,6 +37,7 @@
5 from canonical.launchpad import _
6 from canonical.launchpad.interfaces.validation import valid_webref
7 from canonical.launchpad.validators import LaunchpadValidationError
8+<<<<<<< TREE
9 from lp.blueprints.enums import (
10 SpecificationDefinitionStatus,
11 SpecificationGoalStatus,
12@@ -44,6 +45,14 @@
13 SpecificationLifecycleStatus,
14 SpecificationPriority,
15 )
16+=======
17+from lp.blueprints.enums import (
18+ SpecificationDefinitionStatus,
19+ SpecificationGoalStatus,
20+ SpecificationImplementationStatus,
21+ SpecificationPriority,
22+ )
23+>>>>>>> MERGE-SOURCE
24 from lp.blueprints.interfaces.specificationtarget import IHasSpecifications
25 from lp.blueprints.interfaces.sprint import ISprint
26 from lp.code.interfaces.branchlink import IHasLinkedBranches
27
28=== modified file 'lib/lp/bugs/tests/test_bugtask_search.py'
29--- lib/lp/bugs/tests/test_bugtask_search.py 2010-11-04 15:53:15 +0000
30+++ lib/lp/bugs/tests/test_bugtask_search.py 2010-11-05 17:57:18 +0000
31@@ -486,6 +486,204 @@
32 params = self.getBugTaskSearchParams(user=None, has_cve=True)
33 self.assertSearchFinds(params, self.bugtasks[:1])
34
35+ def setUpFullTextSearchTests(self):
36+ # Set text fields indexed by Bug.fti, BugTask.fti or
37+ # MessageChunk.fti to values we can search for.
38+ for bugtask, number in zip(self.bugtasks, ('one', 'two', 'three')):
39+ commenter = self.bugtasks[0].bug.owner
40+ with person_logged_in(commenter):
41+ bugtask.statusexplanation = 'status explanation %s' % number
42+ bugtask.bug.title = 'bug title %s' % number
43+ bugtask.bug.newMessage(
44+ owner=commenter, content='comment %s' % number)
45+
46+ def test_fulltext_search(self):
47+ # Full text searches find text indexed by Bug.fti...
48+ self.setUpFullTextSearchTests()
49+ params = self.getBugTaskSearchParams(
50+ user=None, searchtext='one title')
51+ search_result = self.runSearch(params)
52+ expected = self.resultValuesForBugtasks(self.bugtasks[:1])
53+ self.assertEqual(expected, search_result)
54+ # ... by BugTask.fti ...
55+ params = self.getBugTaskSearchParams(
56+ user=None, searchtext='two explanation')
57+ search_result = self.runSearch(params)
58+ expected = self.resultValuesForBugtasks(self.bugtasks[1:2])
59+ self.assertEqual(expected, search_result)
60+ # ...and by MessageChunk.fti
61+ params = self.getBugTaskSearchParams(
62+ user=None, searchtext='three comment')
63+ search_result = self.runSearch(params)
64+ expected = self.resultValuesForBugtasks(self.bugtasks[2:3])
65+ self.assertEqual(expected, search_result)
66+
67+ def test_fast_fulltext_search(self):
68+ # Fast full text searches find text indexed by Bug.fti...
69+ self.setUpFullTextSearchTests()
70+ params = self.getBugTaskSearchParams(
71+ user=None, fast_searchtext='one title')
72+ search_result = self.runSearch(params)
73+ expected = self.resultValuesForBugtasks(self.bugtasks[:1])
74+ self.assertEqual(expected, search_result)
75+ # ... but not text indexed by BugTask.fti ...
76+ params = self.getBugTaskSearchParams(
77+ user=None, fast_searchtext='two explanation')
78+ search_result = self.runSearch(params)
79+ self.assertEqual([], search_result)
80+ # ..or by MessageChunk.fti
81+ params = self.getBugTaskSearchParams(
82+ user=None, fast_searchtext='three comment')
83+ search_result = self.runSearch(params)
84+ self.assertEqual([], search_result)
85+
86+ def test_has_no_upstream_bugtask(self):
87+ # Search results can be limited to bugtasks of bugs that do
88+ # not have a related upstream task.
89+ #
90+ # All bugs created in makeBugTasks() have at least one
91+ # bug task for a product: The default bug task created
92+ # by lp.testing.factory.Factory.makeBug() if neither a
93+ # product nor a distribution is specified. For distribution
94+ # related tests we need another bug which does not have
95+ # an upstream (aka product) bug task, otherwise the set of
96+ # bugtasks returned for a search for has_no_upstream_bugtask
97+ # would always be empty.
98+ if (IDistribution.providedBy(self.searchtarget) or
99+ IDistroSeries.providedBy(self.searchtarget) or
100+ ISourcePackage.providedBy(self.searchtarget) or
101+ IDistributionSourcePackage.providedBy(self.searchtarget)):
102+ if IDistribution.providedBy(self.searchtarget):
103+ bug = self.factory.makeBug(distribution=self.searchtarget)
104+ expected = self.resultValuesForBugtasks([bug.default_bugtask])
105+ else:
106+ bug = self.factory.makeBug(
107+ distribution=self.searchtarget.distribution)
108+ bugtask = self.factory.makeBugTask(
109+ bug=bug, target=self.searchtarget)
110+ expected = self.resultValuesForBugtasks([bugtask])
111+ else:
112+ # Bugs without distribution related bugtasks have always at
113+ # least one product related bugtask, hence a
114+ # has_no_upstream_bugtask search will always return an
115+ # empty result set.
116+ expected = []
117+ params = self.getBugTaskSearchParams(
118+ user=None, has_no_upstream_bugtask=True)
119+ search_result = self.runSearch(params)
120+ self.assertEqual(expected, search_result)
121+
122+ def changeStatusOfBugTaskForOtherProduct(self, bugtask, new_status):
123+ # Change the status of another bugtask of the same bug to the
124+ # given status.
125+ bug = bugtask.bug
126+ for other_task in bug.bugtasks:
127+ other_target = other_task.target
128+ if other_task != bugtask and IProduct.providedBy(other_target):
129+ with person_logged_in(other_target.owner):
130+ other_task.transitionToStatus(
131+ new_status, other_target.owner)
132+ return
133+ self.fail(
134+ 'No bug task found for a product that is not the target of '
135+ 'the main test bugtask.')
136+
137+ def test_upstream_status(self):
138+ # Search results can be filtered by the status of an upstream
139+ # bug task.
140+ #
141+ # The bug task status of the default test data has only bug tasks
142+ # with status NEW for the "other" product, hence all bug tasks
143+ # will be returned in a search for bugs that are open upstream.
144+ params = self.getBugTaskSearchParams(user=None, open_upstream=True)
145+ search_result = self.runSearch(params)
146+ expected = self.resultValuesForBugtasks(self.bugtasks)
147+ self.assertEqual(expected, search_result)
148+ # A search for tasks resolved upstream does not yield any bugtask.
149+ params = self.getBugTaskSearchParams(
150+ user=None, resolved_upstream=True)
151+ search_result = self.runSearch(params)
152+ self.assertEqual([], search_result)
153+ # But if we set upstream bug tasks to "fix committed" or "fix
154+ # released", the related bug tasks for our test target appear in
155+ # the search result.
156+ self.changeStatusOfBugTaskForOtherProduct(
157+ self.bugtasks[0], BugTaskStatus.FIXCOMMITTED)
158+ self.changeStatusOfBugTaskForOtherProduct(
159+ self.bugtasks[1], BugTaskStatus.FIXRELEASED)
160+ search_result = self.runSearch(params)
161+ expected = self.resultValuesForBugtasks(self.bugtasks[:2])
162+ self.assertEqual(expected, search_result)
163+ # A search for bug tasks open upstream now returns only one
164+ # test task.
165+ params = self.getBugTaskSearchParams(user=None, open_upstream=True)
166+ search_result = self.runSearch(params)
167+ expected = self.resultValuesForBugtasks(self.bugtasks[2:])
168+
169+ def test_tags(self):
170+ # Search results can be limited to bugs having given tags.
171+ with person_logged_in(self.owner):
172+ self.bugtasks[0].bug.tags = ['tag1', 'tag2']
173+ self.bugtasks[1].bug.tags = ['tag1', 'tag3']
174+ params = self.getBugTaskSearchParams(
175+ user=None, tag=any('tag2', 'tag3'))
176+ search_result = self.runSearch(params)
177+ expected = self.resultValuesForBugtasks(self.bugtasks[:2])
178+ self.assertEqual(expected, search_result)
179+
180+ params = self.getBugTaskSearchParams(
181+ user=None, tag=all('tag2', 'tag3'))
182+ search_result = self.runSearch(params)
183+ self.assertEqual([], search_result)
184+
185+ params = self.getBugTaskSearchParams(
186+ user=None, tag=all('tag1', 'tag3'))
187+ search_result = self.runSearch(params)
188+ expected = self.resultValuesForBugtasks(self.bugtasks[1:2])
189+ self.assertEqual(expected, search_result)
190+
191+ params = self.getBugTaskSearchParams(
192+ user=None, tag=all('tag1', '-tag3'))
193+ search_result = self.runSearch(params)
194+ expected = self.resultValuesForBugtasks(self.bugtasks[:1])
195+ self.assertEqual(expected, search_result)
196+
197+ params = self.getBugTaskSearchParams(
198+ user=None, tag=all('-tag1'))
199+ search_result = self.runSearch(params)
200+ expected = self.resultValuesForBugtasks(self.bugtasks[2:])
201+ self.assertEqual(expected, search_result)
202+
203+ params = self.getBugTaskSearchParams(
204+ user=None, tag=all('*'))
205+ search_result = self.runSearch(params)
206+ expected = self.resultValuesForBugtasks(self.bugtasks[:2])
207+ self.assertEqual(expected, search_result)
208+
209+ params = self.getBugTaskSearchParams(
210+ user=None, tag=all('-*'))
211+ search_result = self.runSearch(params)
212+ expected = self.resultValuesForBugtasks(self.bugtasks[2:])
213+ self.assertEqual(expected, search_result)
214+
215+ def test_date_closed(self):
216+ # Search results can be filtered by the date_closed time
217+ # of a bugtask.
218+ with person_logged_in(self.owner):
219+ self.bugtasks[2].transitionToStatus(
220+ BugTaskStatus.FIXRELEASED, self.owner)
221+ utc_now = datetime.now(pytz.timezone('UTC'))
222+ self.assertTrue(utc_now >= self.bugtasks[2].date_closed)
223+ params = self.getBugTaskSearchParams(
224+ user=None, date_closed=greater_than(utc_now-timedelta(days=1)))
225+ search_result = self.runSearch(params)
226+ expected = self.resultValuesForBugtasks(self.bugtasks[2:])
227+ self.assertEqual(expected, search_result)
228+ params = self.getBugTaskSearchParams(
229+ user=None, date_closed=greater_than(utc_now+timedelta(days=1)))
230+ search_result = self.runSearch(params)
231+ self.assertEqual([], search_result)
232+
233
234 class ProductAndDistributionTests:
235 """Tests which are useful for distributions and products."""
236@@ -503,8 +701,15 @@
237 with person_logged_in(self.owner):
238 self.bugtasks[0].bug.addNomination(nominator, series1)
239 self.bugtasks[1].bug.addNomination(nominator, series2)
240+<<<<<<< TREE
241 params = self.getBugTaskSearchParams(user=None, nominated_for=series1)
242 self.assertSearchFinds(params, self.bugtasks[:1])
243+=======
244+ params = self.getBugTaskSearchParams(user=None, nominated_for=series1)
245+ search_result = self.runSearch(params)
246+ expected = self.resultValuesForBugtasks(self.bugtasks[:1])
247+ self.assertEqual(expected, search_result)
248+>>>>>>> MERGE-SOURCE
249
250
251 class BugTargetTestBase:
252
253=== modified file 'lib/lp/code/browser/sourcepackagerecipe.py'
254--- lib/lp/code/browser/sourcepackagerecipe.py 2010-10-29 00:07:20 +0000
255+++ lib/lp/code/browser/sourcepackagerecipe.py 2010-11-05 17:57:18 +0000
256@@ -274,10 +274,16 @@
257 'build_daily',
258 ])
259 daily_build_archive = Choice(vocabulary='TargetPPAs',
260- title=u'Daily build archive')
261+ title=u'Daily build archive',
262+ description=(
263+ u'If built daily, this is the archive where the package '
264+ u'will be uploaded.'))
265 distros = List(
266 Choice(vocabulary='BuildableDistroSeries'),
267- title=u'Default Distribution series')
268+ title=u'Default distribution series',
269+ description=(
270+ u'If built daily, these are the distribution versions that '
271+ u'the recipe will be built for.'))
272 recipe_text = Text(
273 title=u'Recipe text', required=True,
274 description=u'The text of the recipe.')
275
276=== modified file 'lib/lp/code/help/related-recipes.html'
277--- lib/lp/code/help/related-recipes.html 2010-11-04 22:50:52 +0000
278+++ lib/lp/code/help/related-recipes.html 2010-11-05 17:57:18 +0000
279@@ -1,3 +1,4 @@
280+<<<<<<< TREE
281 <html>
282 <head>
283 <title>Related source package recipes</title>
284@@ -36,3 +37,35 @@
285
286 </body>
287 </html>
288+=======
289+<html>
290+ <head>
291+ <title>Related source package recipes</title>
292+ <link rel="stylesheet" type="text/css"
293+ href="/+icing/yui/cssreset/reset.css" />
294+ <link rel="stylesheet" type="text/css"
295+ href="/+icing/yui/cssfonts/fonts.css" />
296+ <link rel="stylesheet" type="text/css"
297+ href="/+icing/yui/cssbase/base.css" />
298+ </head>
299+ <body>
300+ <h1>Related source package recipes</h1>
301+
302+ <p>
303+ You can ask Launchpad to make an automatic daily build
304+ of the code in this branch and place the resultant package(s)
305+ in your chosen PPA. (<a href="https://help.launchpad.net/Packaging/SourceBuilds" target="_blank">Read more</a>)
306+ </p>
307+
308+ <p>A "recipe" is a description of the steps bzr-builder should take to
309+ construct a source package from the various bzr branches. Its format
310+ specifies:</p>
311+ <ul class="bulleted">
312+ <li>where to use the code from (trunk branch, beta branch, etc.), where to get the packaging from (separate branch? ubuntu branch?)</li>
313+ <li>the correct package version (so users will still be able to upgrade to the stable version of the distro once it gets released)</li>
314+ <li>what to modify to make the source build properly</li>
315+ </ul>
316+
317+ </body>
318+</html>
319+>>>>>>> MERGE-SOURCE
320
321=== modified file 'lib/lp/code/interfaces/sourcepackagerecipe.py'
322--- lib/lp/code/interfaces/sourcepackagerecipe.py 2010-11-05 07:43:04 +0000
323+++ lib/lp/code/interfaces/sourcepackagerecipe.py 2010-11-05 17:57:18 +0000
324@@ -55,6 +55,7 @@
325 from lp.registry.interfaces.role import IHasOwner
326 from lp.services import features
327 from lp.services.fields import (
328+ Description,
329 PersonChoice,
330 PublicPersonChoice,
331 )
332@@ -179,7 +180,7 @@
333 constraint=name_validator,
334 description=_("The name of this recipe.")))
335
336- description = Text(
337+ description = Description(
338 title=_('Description'), required=True,
339 description=_('A short description of the recipe.'))
340