Merge lp:~flacoste/launchpad/bug-781993-2 into lp:launchpad

Proposed by Francis J. Lacoste
Status: Merged
Approved by: Francis J. Lacoste
Approved revision: no longer in the source branch.
Merged at revision: 13263
Proposed branch: lp:~flacoste/launchpad/bug-781993-2
Merge into: lp:launchpad
Prerequisite: lp:~flacoste/launchpad/bug-781993-1
Diff against target: 249 lines (+85/-16)
7 files modified
lib/lp/bugs/browser/bugtarget.py (+11/-0)
lib/lp/bugs/browser/tests/bug-views.txt (+9/-6)
lib/lp/bugs/browser/tests/test_bugtarget_filebug.py (+32/-0)
lib/lp/bugs/model/bug.py (+2/-6)
lib/lp/registry/interfaces/distribution.py (+6/-2)
lib/lp/registry/model/distribution.py (+13/-2)
lib/lp/registry/tests/test_distribution.py (+12/-0)
To merge this branch: bzr merge lp:~flacoste/launchpad/bug-781993-2
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+65058@code.launchpad.net

Commit message

[r=bac][bug=781993] Allow filing bugs against source package with an official package branch.

Description of the change

= Summary =

We want to be able to file bugs in the Ensemble Principia distribution
(https://launchpad.net/principia). That distribution doesn't have published
source package, but they have official source package branch.

It builds on the previous guessPublishedSourcePackageName refactoring.

== Proposed fix ==

Allow filing a bug on a source package if it has official source package
branch.

== Pre-implementation notes ==

== Implementation details ==

 * If no published source package is found, it looks for official source
 package branches for it.

== Tests ==

In addition to the unit test for guessPublishedSourcePackageName, I added an
integration test just to make sure that we don't regress that functionality.
(By changing the vocabulary for example, they are currently very lax and will
allow any valid source or binary package names. If we were to make them more
context sensitive, it might be a problem if official package branches weren't
considered.)

 ./bin/test -vvt 'test_guessPublished|TestFileBugSourcePackage'

== Demo and Q/A ==

Try filing a sourcepackage bug on qastaging on the the principia distribution.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/bugs/stories/guided-filebug/xx-bug-reporting-tools.txt
  lib/lp/bugs/browser/bugtarget.py
  lib/lp/bugs/doc/bugzilla-import.txt
  lib/lp/bugs/browser/widgets/bugtask.py
  lib/lp/bugs/browser/tests/bug-views.txt
  lib/canonical/launchpad/interfaces/validation.py
  lib/lp/testing/factory.py
  lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
  lib/lp/bugs/model/bug.py
  lib/lp/soyuz/doc/distribution.txt
  cronscripts/update-debwatches.py
  lib/lp/bugs/doc/bugtask-package-widget.txt
  lib/lp/registry/interfaces/distribution.py
  lib/lp/app/widgets/launchpadtarget.py
  lib/canonical/launchpad/scripts/debsync.py
  lib/lp/registry/tests/test_distribution.py
  lib/lp/bugs/scripts/bugzilla.py
  lib/lp/registry/model/distribution.py
  lib/lp/bugs/xmlrpc/bug.py
  lib/lp/bugs/interfaces/bug.py

./lib/lp/bugs/browser/tests/bug-views.txt
     195: source has trailing whitespace.
./lib/lp/bugs/model/bug.py
      52: 'SQLRaw' imported but unused
      52: 'Join' imported but unused
      52: 'Exists' imported but unused
     171: 'get_bug_privacy_filter' imported but unused
      52: 'Count' imported but unused
     304: E301 expected 1 blank line, found 0
    2590: E225 missing whitespace around operator
./cronscripts/update-debwatches.py
       9: '_pythonpath' imported but unused
./lib/lp/bugs/scripts/bugzilla.py
       8: Line exceeds 78 characters.

I'll fix this post-review.

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

This branch looks good Francis.

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/bugs/browser/bugtarget.py'
2--- lib/lp/bugs/browser/bugtarget.py 2011-06-17 21:17:24 +0000
3+++ lib/lp/bugs/browser/bugtarget.py 2011-06-17 21:17:26 +0000
4@@ -329,6 +329,17 @@
5 self.extra_data = FileBugData()
6
7 def initialize(self):
8+ # redirect_ubuntu_filebug is a cached_property.
9+ # Access it first just to compute its value. Because it
10+ # makes a DB access to get the bug supervisor, it causes
11+ # trouble in tests when form validation errors occur. Because the
12+ # transaction is doomed, the storm cache is invalidated and accessing
13+ # the property will result in a a LostObjectError, because
14+ # the created objects disappeared. Not likely a problem in production
15+ # since the objects will still be in the DB, but doesn't hurt there
16+ # either. It makes for better diagnosis of failing tests.
17+ if self.redirect_ubuntu_filebug:
18+ pass
19 LaunchpadFormView.initialize(self)
20 if (not self.redirect_ubuntu_filebug and
21 self.extra_data_token is not None and
22
23=== modified file 'lib/lp/bugs/browser/tests/bug-views.txt'
24--- lib/lp/bugs/browser/tests/bug-views.txt 2011-06-17 21:17:24 +0000
25+++ lib/lp/bugs/browser/tests/bug-views.txt 2011-06-17 21:17:26 +0000
26@@ -25,7 +25,8 @@
27 if the user provides a valid package name when reporting the bug.
28
29 If the package name entered by the user happens to be a binary package
30-name, the bug is filed against the source package used to build that binary.
31+name, that information is recorded in the description, and the first
32+comment, of the bug report.
33
34 >>> from zope.component import getMultiAdapter, getUtility
35 >>> from canonical.launchpad.webapp.interfaces import (
36@@ -69,7 +70,13 @@
37
38 >>> latest_ubuntu_bugtask = ubuntu.searchTasks(search_params)[0]
39
40-The source package from which the binary was built has been set on
41+The user specified a binary package name, so that's been added to the
42+bug description and the first comment:
43+
44+ >>> print latest_ubuntu_bugtask.bug.description
45+ a bug in a bin pkg
46+
47+the source package from which the binary was built has been set on
48 the bugtask.
49
50 >>> print latest_ubuntu_bugtask.sourcepackagename.name
51@@ -156,11 +163,7 @@
52 3
53 >>> [ (c.index, c.owner.name, c.text_contents)
54 ... for c in ubuntu_bugview.comments ]
55-<<<<<<< TREE
56- [(0, u'name16', u'Binary package hint: linux-2.6.12...'),
57-=======
58 [(0, u'name16', u'a bug in a bin pkg'),
59->>>>>>> MERGE-SOURCE
60 (1, u'name16', u'I can reproduce this bug.'),
61 (2, u'name16', u'I can reproduce this bug.')]
62
63
64=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_filebug.py'
65--- lib/lp/bugs/browser/tests/test_bugtarget_filebug.py 2011-04-29 01:55:28 +0000
66+++ lib/lp/bugs/browser/tests/test_bugtarget_filebug.py 2011-06-17 21:17:26 +0000
67@@ -8,6 +8,7 @@
68 TooLong,
69 TooShort,
70 )
71+from zope.security.proxy import removeSecurityProxy
72
73 from canonical.launchpad.ftests import login
74 from canonical.launchpad.testing.pages import (
75@@ -21,6 +22,7 @@
76 FileBugViewBase,
77 )
78 from lp.bugs.interfaces.bug import IBugAddForm
79+from lp.bugs.publisher import BugsLayer
80 from lp.testing import (
81 login_person,
82 TestCaseWithFactory,
83@@ -394,3 +396,33 @@
84 "source": product.displayname, "content": u"Include bug details",
85 }]
86 self.assertEqual(expected_guidelines, view.bug_reporting_guidelines)
87+
88+
89+class TestFileBugSourcePackage(TestCaseWithFactory):
90+
91+ layer = DatabaseFunctionalLayer
92+
93+ def test_filebug_works_on_official_package_branch(self):
94+ # It should be possible to file a bug against a source package
95+ # when there is an official package branch.
96+ user = self.factory.makePerson()
97+ sourcepackage = self.factory.makeSourcePackage('my-package')
98+ self.factory.makeRelatedBranchesForSourcePackage(
99+ sourcepackage=sourcepackage)
100+ removeSecurityProxy(sourcepackage.distribution).official_malone = True
101+ login_person(user)
102+
103+ view = create_initialized_view(
104+ context=sourcepackage.distribution, name='+filebug',
105+ form={
106+ 'field.title': 'A bug',
107+ 'field.comment': 'A comment',
108+ 'field.bugtarget.distribution': (
109+ sourcepackage.distribution.name),
110+ 'field.packagename': 'my-package',
111+ 'field.actions.submit_bug': 'Submit Bug Request',
112+ }, layer=BugsLayer, principal=user)
113+ msg = "\n".join([
114+ notification.message
115+ for notification in view.request.response.notifications])
116+ self.assertIn("Thank you for your bug report.", msg)
117
118=== modified file 'lib/lp/bugs/model/bug.py'
119--- lib/lp/bugs/model/bug.py 2011-06-17 21:17:24 +0000
120+++ lib/lp/bugs/model/bug.py 2011-06-17 21:17:26 +0000
121@@ -51,18 +51,14 @@
122 )
123 from storm.expr import (
124 And,
125- Count,
126 Desc,
127- Exists,
128 In,
129- Join,
130 LeftJoin,
131 Max,
132 Not,
133 Or,
134 Select,
135 SQL,
136- SQLRaw,
137 Sum,
138 Union,
139 )
140@@ -171,7 +167,6 @@
141 from lp.bugs.model.bugtask import (
142 BugTask,
143 bugtask_sort_key,
144- get_bug_privacy_filter,
145 )
146 from lp.bugs.model.bugwatch import BugWatch
147 from lp.bugs.model.structuralsubscription import (
148@@ -300,6 +295,7 @@
149 ))
150 sum_count = Sum(BugSummary.count)
151 tag_count_columns = (BugSummary.tag, sum_count)
152+
153 # Always query for used
154 def _query(*args):
155 return store.find(tag_count_columns, *(where_conditions + list(args))
156@@ -2605,7 +2601,7 @@
157 # one source package, it will be returned more than one time. 4
158 # is an arbitrary number that should be large enough.
159 bugs = []
160- for bug_task in bug_tasks[:4*limit]:
161+ for bug_task in bug_tasks[:4 * limit]:
162 bug = bug_task.bug
163 duplicateof = bug.duplicateof
164 if duplicateof is not None:
165
166=== modified file 'lib/lp/registry/interfaces/distribution.py'
167--- lib/lp/registry/interfaces/distribution.py 2011-06-17 21:17:24 +0000
168+++ lib/lp/registry/interfaces/distribution.py 2011-06-17 21:17:26 +0000
169@@ -570,8 +570,12 @@
170 def guessPublishedSourcePackageName(pkgname):
171 """Return the "published" SourcePackageName related to pkgname.
172
173- If pkgname is corresponds to a source package that was published in
174- any of the distribution series.
175+ If pkgname corresponds to a source package that was published in
176+ any of the distribution series, that's the SourcePackageName that is
177+ returned.
178+
179+ If there is any official source package branch linked, then that
180+ source package name is returned.
181
182 Otherwise, try to find a published binary package name and then return
183 the source package name from which it comes from.
184
185=== modified file 'lib/lp/registry/model/distribution.py'
186--- lib/lp/registry/model/distribution.py 2011-06-17 21:17:24 +0000
187+++ lib/lp/registry/model/distribution.py 2011-06-17 21:17:26 +0000
188@@ -119,10 +119,12 @@
189 HasBugHeatMixin,
190 OfficialBugTagTargetMixin,
191 )
192-from lp.bugs.model.bugtask import BugTask
193 from lp.bugs.model.structuralsubscription import (
194 StructuralSubscriptionTargetMixin,
195 )
196+from lp.code.interfaces.seriessourcepackagebranch import (
197+ IFindOfficialBranchLinks,
198+ )
199 from lp.registry.errors import NoSuchDistroSeries
200 from lp.registry.interfaces.distribution import (
201 IBaseDistribution,
202@@ -649,7 +651,8 @@
203 """See `IBugTarget`."""
204 return get_bug_tags("BugTask.distribution = %s" % sqlvalues(self))
205
206- def getUsedBugTagsWithOpenCounts(self, user, tag_limit=0, include_tags=None):
207+ def getUsedBugTagsWithOpenCounts(self, user, tag_limit=0,
208+ include_tags=None):
209 """See IBugTarget."""
210 # Circular fail.
211 from lp.bugs.model.bugsummary import BugSummary
212@@ -1407,6 +1410,14 @@
213 if publishing is not None:
214 return sourcepackagename
215
216+ # Look to see if there is an official source package branch.
217+ # That's considered "published" enough.
218+ branch_links = getUtility(IFindOfficialBranchLinks)
219+ results = branch_links.findForDistributionSourcePackage(
220+ self.getSourcePackage(sourcepackagename))
221+ if results.any() is not None:
222+ return sourcepackagename
223+
224 # At this point we don't have a published source package by
225 # that name, so let's try to find a binary package and work
226 # back from there.
227
228=== modified file 'lib/lp/registry/tests/test_distribution.py'
229--- lib/lp/registry/tests/test_distribution.py 2011-06-17 21:17:24 +0000
230+++ lib/lp/registry/tests/test_distribution.py 2011-06-17 21:17:26 +0000
231@@ -168,6 +168,18 @@
232 distroseries.distribution.guessPublishedSourcePackageName(
233 'my-package').name)
234
235+ def test_guessPublishedSourcePackageName_official_package_branch(self):
236+ # It consider that a sourcepackage that has an official package
237+ # branch is published.
238+ sourcepackage = self.factory.makeSourcePackage(
239+ sourcepackagename='my-package')
240+ self.factory.makeRelatedBranchesForSourcePackage(
241+ sourcepackage=sourcepackage)
242+ self.assertEquals(
243+ 'my-package',
244+ sourcepackage.distribution.guessPublishedSourcePackageName(
245+ 'my-package').name)
246+
247
248 class TestDistributionCurrentSourceReleases(
249 TestDistroSeriesCurrentSourceReleases):