Merge lp:~wgrant/launchpad/xref-buglinks-cleanup into lp:launchpad

Proposed by William Grant
Status: Merged
Merged at revision: 17805
Proposed branch: lp:~wgrant/launchpad/xref-buglinks-cleanup
Merge into: lp:launchpad
Prerequisite: lp:~wgrant/launchpad/xref-buglinks
Diff against target: 1112 lines (+88/-510)
19 files modified
database/sampledata/current-dev.sql (+13/-0)
database/sampledata/current.sql (+13/-0)
database/schema/security.cfg (+0/-15)
lib/lp/answers/model/question.py (+15/-39)
lib/lp/blueprints/model/specification.py (+3/-16)
lib/lp/blueprints/model/specificationbug.py (+0/-20)
lib/lp/blueprints/tests/test_specification.py (+0/-17)
lib/lp/bugs/model/bug.py (+10/-31)
lib/lp/bugs/model/bugcve.py (+0/-22)
lib/lp/bugs/model/bugtask.py (+5/-12)
lib/lp/bugs/model/bugtasksearch.py (+18/-35)
lib/lp/bugs/model/cve.py (+11/-40)
lib/lp/bugs/model/tests/test_bugtask.py (+0/-16)
lib/lp/bugs/model/tests/test_bugtasksearch.py (+0/-21)
lib/lp/bugs/tests/test_cve.py (+0/-33)
lib/lp/coop/answersbugs/model.py (+0/-25)
lib/lp/coop/answersbugs/tests/test_questionbug.py (+0/-17)
lib/lp/scripts/garbo.py (+0/-63)
lib/lp/scripts/tests/test_garbo.py (+0/-88)
To merge this branch: bzr merge lp:~wgrant/launchpad/xref-buglinks-cleanup
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+272592@code.launchpad.net

Commit message

BugCve/QuestionBug/SpecificationBug -> XRef, part 2: Delete old model.

Description of the change

BugCve/QuestionBug/SpecificationBug -> XRef, part 2: Delete old model.

All the new feature flags die, and the old IBugLink implementations are gone.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database/sampledata/current-dev.sql'
2--- database/sampledata/current-dev.sql 2015-08-24 12:25:10 +0000
3+++ database/sampledata/current-dev.sql 2015-10-08 08:52:56 +0000
4@@ -11421,3 +11421,16 @@
5
6
7
8+ALTER TABLE xref DISABLE TRIGGER ALL;
9+
10+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('bug', '1', 1, 'cve', '1999-8979', NULL, NULL, '2015-09-28 04:56:11.203306', NULL);
11+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('bug', '1', 1, 'specification', '3', 3, NULL, '2015-09-28 04:56:11.203306', NULL);
12+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('bug', '2', 2, 'cve', '1999-2345', NULL, NULL, '2015-09-28 04:56:11.212965', NULL);
13+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('cve', '1999-2345', NULL, 'bug', '2', 2, NULL, '2015-09-28 04:56:11.212965', NULL);
14+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('cve', '1999-8979', NULL, 'bug', '1', 1, NULL, '2015-09-28 04:56:11.203306', NULL);
15+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('specification', '3', 3, 'bug', '1', 1, NULL, '2015-09-28 04:56:11.203306', NULL);
16+
17+
18+ALTER TABLE xref ENABLE TRIGGER ALL;
19+
20+
21
22=== modified file 'database/sampledata/current.sql'
23--- database/sampledata/current.sql 2015-08-24 12:25:10 +0000
24+++ database/sampledata/current.sql 2015-10-08 08:52:56 +0000
25@@ -11336,3 +11336,16 @@
26
27
28
29+ALTER TABLE xref DISABLE TRIGGER ALL;
30+
31+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('bug', '1', 1, 'cve', '1999-8979', NULL, NULL, '2015-09-28 04:55:28.528879', NULL);
32+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('bug', '1', 1, 'specification', '3', 3, NULL, '2015-09-28 04:55:28.528879', NULL);
33+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('bug', '2', 2, 'cve', '1999-2345', NULL, NULL, '2015-09-28 04:55:28.540059', NULL);
34+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('cve', '1999-2345', NULL, 'bug', '2', 2, NULL, '2015-09-28 04:55:28.540059', NULL);
35+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('cve', '1999-8979', NULL, 'bug', '1', 1, NULL, '2015-09-28 04:55:28.528879', NULL);
36+INSERT INTO xref (from_type, from_id, from_id_int, to_type, to_id, to_id_int, creator, date_created, metadata) VALUES ('specification', '3', 3, 'bug', '1', 1, NULL, '2015-09-28 04:55:28.528879', NULL);
37+
38+
39+ALTER TABLE xref ENABLE TRIGGER ALL;
40+
41+
42
43=== modified file 'database/schema/security.cfg'
44--- database/schema/security.cfg 2015-09-28 08:19:32 +0000
45+++ database/schema/security.cfg 2015-10-08 08:52:56 +0000
46@@ -144,7 +144,6 @@
47 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
48 public.bugattachment = SELECT, INSERT, UPDATE, DELETE
49 public.bugbranch = SELECT, INSERT, UPDATE, DELETE
50-public.bugcve = SELECT, INSERT, DELETE
51 public.bugnomination = SELECT, UPDATE
52 public.bugnotification = SELECT, INSERT, UPDATE, DELETE
53 public.bugnotificationattachment = SELECT, INSERT
54@@ -277,7 +276,6 @@
55 public.project = SELECT
56 public.publisherconfig = SELECT, INSERT, UPDATE, DELETE
57 public.question = SELECT, INSERT, UPDATE
58-public.questionbug = SELECT, INSERT, DELETE
59 public.questionjob = SELECT, INSERT, UPDATE, DELETE
60 public.questionmessage = SELECT, INSERT
61 public.questionreopening = SELECT, INSERT, UPDATE
62@@ -302,7 +300,6 @@
63 public.sourcepackagerecipedistroseries = SELECT, INSERT, DELETE
64 public.specification = SELECT, INSERT, UPDATE
65 public.specificationbranch = SELECT, INSERT, UPDATE, DELETE
66-public.specificationbug = SELECT, INSERT, DELETE
67 public.specificationdependency = SELECT, INSERT, DELETE
68 public.specificationmessage = SELECT, INSERT
69 public.specificationsubscription = SELECT, INSERT, UPDATE, DELETE
70@@ -598,7 +595,6 @@
71 public.bug = SELECT, INSERT, UPDATE
72 public.bugactivity = SELECT, INSERT
73 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
74-public.bugcve = SELECT, INSERT
75 public.bugmessage = SELECT, INSERT, UPDATE
76 public.bugmute = SELECT
77 public.bugnomination = SELECT
78@@ -642,7 +638,6 @@
79 public.project = SELECT, UPDATE
80 public.question = SELECT
81 public.questionjob = SELECT, INSERT
82-public.questionbug = SELECT
83 public.questionsubscription = SELECT
84 public.section = SELECT
85 public.sourcepackagename = SELECT
86@@ -890,7 +885,6 @@
87 public.bug = SELECT, UPDATE
88 public.bugactivity = SELECT, INSERT
89 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
90-public.bugcve = SELECT, INSERT
91 public.bugmessage = SELECT, INSERT
92 public.bugnomination = SELECT
93 public.bugnotification = SELECT, INSERT
94@@ -937,7 +931,6 @@
95 public.project = SELECT
96 public.publisherconfig = SELECT, INSERT
97 public.question = SELECT
98-public.questionbug = SELECT
99 public.questionjob = SELECT, INSERT
100 public.questionsubscription = SELECT
101 public.sourcepackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE
102@@ -1288,7 +1281,6 @@
103 public.personlanguage = SELECT
104 public.product = SELECT
105 public.question = SELECT, UPDATE
106-public.questionbug = SELECT
107 public.questionjob = SELECT, INSERT
108 public.questionmessage = SELECT, INSERT
109 public.questionsubscription = SELECT
110@@ -1347,7 +1339,6 @@
111 public.bug = SELECT, UPDATE
112 public.bugactivity = SELECT, INSERT
113 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
114-public.bugcve = SELECT, INSERT
115 public.bugmessage = SELECT, INSERT
116 public.bugmute = SELECT
117 public.bugnomination = SELECT
118@@ -1414,7 +1405,6 @@
119 public.productseries = SELECT
120 public.project = SELECT, UPDATE
121 public.question = SELECT
122-public.questionbug = SELECT
123 public.questionjob = SELECT, INSERT
124 public.questionsubscription = SELECT
125 public.section = SELECT, INSERT
126@@ -1461,7 +1451,6 @@
127 public.bug = SELECT, UPDATE
128 public.bugactivity = SELECT, INSERT
129 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
130-public.bugcve = SELECT, INSERT
131 public.bugmessage = SELECT, INSERT
132 public.bugmute = SELECT
133 public.bugnomination = SELECT
134@@ -1530,7 +1519,6 @@
135 public.project = SELECT, UPDATE
136 public.publisherconfig = SELECT
137 public.question = SELECT
138-public.questionbug = SELECT
139 public.questionjob = SELECT, INSERT
140 public.questionsubscription = SELECT
141 public.section = SELECT
142@@ -1617,7 +1605,6 @@
143 public.productseries = SELECT
144 public.project = SELECT, UPDATE
145 public.question = SELECT
146-public.questionbug = SELECT
147 public.questionjob = SELECT, INSERT
148 public.questionsubscription = SELECT
149 public.section = SELECT
150@@ -1765,7 +1752,6 @@
151 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
152 public.bugattachment = SELECT, INSERT
153 public.bugbranch = SELECT
154-public.bugcve = SELECT, INSERT
155 public.bugmessage = SELECT, INSERT
156 public.bugmute = SELECT
157 public.bugnomination = SELECT, INSERT, UPDATE
158@@ -1824,7 +1810,6 @@
159 public.productseries = SELECT
160 public.project = SELECT, UPDATE
161 public.question = SELECT, UPDATE
162-public.questionbug = SELECT
163 public.questionjob = SELECT, INSERT
164 public.questionmessage = SELECT, INSERT
165 public.questionsubscription = SELECT
166
167=== modified file 'lib/lp/answers/model/question.py'
168--- lib/lp/answers/model/question.py 2015-10-01 11:40:45 +0000
169+++ lib/lp/answers/model/question.py 2015-10-08 08:52:56 +0000
170@@ -77,7 +77,6 @@
171 from lp.bugs.interfaces.buglink import IBugLinkTarget
172 from lp.bugs.interfaces.bugtask import BugTaskStatus
173 from lp.bugs.model.buglinktarget import BugLinkTargetMixin
174-from lp.coop.answersbugs.model import QuestionBug
175 from lp.registry.interfaces.distribution import (
176 IDistribution,
177 IDistributionSet,
178@@ -101,7 +100,6 @@
179 )
180 from lp.services.database.datetimecol import UtcDateTimeCol
181 from lp.services.database.enumcol import EnumCol
182-from lp.services.database.interfaces import IStore
183 from lp.services.database.nl_search import nl_phrase_search
184 from lp.services.database.sqlbase import (
185 cursor,
186@@ -110,7 +108,6 @@
187 sqlvalues,
188 )
189 from lp.services.database.stormexpr import rank_by_fti
190-from lp.services.features import getFeatureFlag
191 from lp.services.mail.notificationrecipientset import NotificationRecipientSet
192 from lp.services.messages.interfaces.message import IMessage
193 from lp.services.messages.model.message import (
194@@ -665,30 +662,21 @@
195 @property
196 def bugs(self):
197 from lp.bugs.model.bug import Bug
198- if getFeatureFlag('bugs.xref_buglinks.query'):
199- bug_ids = [
200- int(id) for _, id in getUtility(IXRefSet).findFrom(
201- (u'question', unicode(self.id)), types=[u'bug'])]
202- else:
203- bug_ids = list(IStore(QuestionBug).find(
204- QuestionBug,
205- QuestionBug.question == self).values(QuestionBug.bugID))
206+ bug_ids = [
207+ int(id) for _, id in getUtility(IXRefSet).findFrom(
208+ (u'question', unicode(self.id)), types=[u'bug'])]
209 return list(sorted(
210 bulk.load(Bug, bug_ids), key=operator.attrgetter('id')))
211
212 # IBugLinkTarget implementation
213 def createBugLink(self, bug):
214 """See BugLinkTargetMixin."""
215- if not getFeatureFlag('bugs.xref_buglinks.write_old.disabled'):
216- QuestionBug(question=self, bug=bug)
217 # XXX: Should set creator.
218 getUtility(IXRefSet).create(
219 {(u'question', unicode(self.id)): {(u'bug', unicode(bug.id)): {}}})
220
221 def deleteBugLink(self, bug):
222 """See BugLinkTargetMixin."""
223- if not getFeatureFlag('bugs.xref_buglinks.write_old.disabled'):
224- Store.of(self).find(QuestionBug, question=self, bug=bug).remove()
225 getUtility(IXRefSet).delete(
226 {(u'question', unicode(self.id)): [(u'bug', unicode(bug.id))]})
227
228@@ -716,38 +704,26 @@
229 # This query joins to bugtasks that are not BugTaskStatus.INVALID
230 # because there are many bugtasks to one question. A question is
231 # included when BugTask.status IS NULL.
232- if getFeatureFlag('bugs.xref_buglinks.query'):
233- bugtask_join = """
234- LEFT OUTER JOIN XRef ON (
235- XRef.from_type = 'question'
236- AND XRef.from_id_int = Question.id
237- AND XRef.to_type = 'bug')
238- LEFT OUTER JOIN BugTask ON (
239- BugTask.bug = XRef.to_id_int
240- AND BugTask.status != %s)
241- """
242- else:
243- bugtask_join = """
244- LEFT OUTER JOIN QuestionBug
245- ON Question.id = QuestionBug.question
246- LEFT OUTER JOIN BugTask ON (
247- BugTask.bug = QuestionBug.bug
248- AND BugTask.status != %s)
249- """
250- return Question.select(("""
251+ return Question.select("""
252 id in (SELECT Question.id
253 FROM Question
254- %s
255+ LEFT OUTER JOIN XRef ON (
256+ XRef.from_type = 'question'
257+ AND XRef.from_id_int = Question.id
258+ AND XRef.to_type = 'bug')
259+ LEFT OUTER JOIN BugTask ON (
260+ BugTask.bug = XRef.to_id_int
261+ AND BugTask.status != %s)
262 WHERE
263- Question.status IN (%%s, %%s)
264+ Question.status IN (%s, %s)
265 AND (Question.datelastresponse IS NULL
266 OR Question.datelastresponse < (CURRENT_TIMESTAMP
267- AT TIME ZONE 'UTC' - interval '%%s days'))
268+ AT TIME ZONE 'UTC' - interval '%s days'))
269 AND Question.datelastquery < (CURRENT_TIMESTAMP
270- AT TIME ZONE 'UTC' - interval '%%s days')
271+ AT TIME ZONE 'UTC' - interval '%s days')
272 AND Question.assignee IS NULL
273 AND BugTask.status IS NULL)
274- """ % bugtask_join) % sqlvalues(
275+ """ % sqlvalues(
276 BugTaskStatus.INVALID,
277 QuestionStatus.OPEN, QuestionStatus.NEEDSINFO,
278 days_before_expiration, days_before_expiration))
279
280=== modified file 'lib/lp/blueprints/model/specification.py'
281--- lib/lp/blueprints/model/specification.py 2015-10-01 11:40:45 +0000
282+++ lib/lp/blueprints/model/specification.py 2015-10-08 08:52:56 +0000
283@@ -64,7 +64,6 @@
284 ISpecificationSet,
285 )
286 from lp.blueprints.model.specificationbranch import SpecificationBranch
287-from lp.blueprints.model.specificationbug import SpecificationBug
288 from lp.blueprints.model.specificationdependency import (
289 SpecificationDependency,
290 )
291@@ -102,7 +101,6 @@
292 SQLBase,
293 sqlvalues,
294 )
295-from lp.services.features import getFeatureFlag
296 from lp.services.mail.helpers import get_contact_email_addresses
297 from lp.services.propertycache import (
298 cachedproperty,
299@@ -796,22 +794,14 @@
300 @property
301 def bugs(self):
302 from lp.bugs.model.bug import Bug
303- if getFeatureFlag('bugs.xref_buglinks.query'):
304- bug_ids = [
305- int(id) for _, id in getUtility(IXRefSet).findFrom(
306- (u'specification', unicode(self.id)), types=[u'bug'])]
307- else:
308- bug_ids = list(IStore(SpecificationBug).find(
309- SpecificationBug,
310- SpecificationBug.specification == self).values(
311- SpecificationBug.bugID))
312+ bug_ids = [
313+ int(id) for _, id in getUtility(IXRefSet).findFrom(
314+ (u'specification', unicode(self.id)), types=[u'bug'])]
315 return list(sorted(
316 bulk.load(Bug, bug_ids), key=operator.attrgetter('id')))
317
318 def createBugLink(self, bug):
319 """See BugLinkTargetMixin."""
320- if not getFeatureFlag('bugs.xref_buglinks.write_old.disabled'):
321- SpecificationBug(specification=self, bug=bug)
322 # XXX: Should set creator.
323 getUtility(IXRefSet).create(
324 {(u'specification', unicode(self.id)):
325@@ -819,9 +809,6 @@
326
327 def deleteBugLink(self, bug):
328 """See BugLinkTargetMixin."""
329- if not getFeatureFlag('bugs.xref_buglinks.write_old.disabled'):
330- Store.of(self).find(
331- SpecificationBug, specification=self, bug=bug).remove()
332 getUtility(IXRefSet).delete(
333 {(u'specification', unicode(self.id)):
334 [(u'bug', unicode(bug.id))]})
335
336=== removed file 'lib/lp/blueprints/model/specificationbug.py'
337--- lib/lp/blueprints/model/specificationbug.py 2015-09-25 10:15:37 +0000
338+++ lib/lp/blueprints/model/specificationbug.py 1970-01-01 00:00:00 +0000
339@@ -1,20 +0,0 @@
340-# Copyright 2009 Canonical Ltd. This software is licensed under the
341-# GNU Affero General Public License version 3 (see the file LICENSE).
342-
343-__metaclass__ = type
344-
345-__all__ = ['SpecificationBug']
346-
347-from sqlobject import ForeignKey
348-
349-from lp.services.database.sqlbase import SQLBase
350-
351-
352-class SpecificationBug(SQLBase):
353- """A link between a spec and a bug."""
354-
355- _table = 'SpecificationBug'
356- specification = ForeignKey(dbName='specification',
357- foreignKey='Specification', notNull=True)
358- bug = ForeignKey(dbName='bug', foreignKey='Bug',
359- notNull=True)
360
361=== modified file 'lib/lp/blueprints/tests/test_specification.py'
362--- lib/lp/blueprints/tests/test_specification.py 2015-09-28 08:13:36 +0000
363+++ lib/lp/blueprints/tests/test_specification.py 2015-10-08 08:52:56 +0000
364@@ -59,7 +59,6 @@
365 EditSpecificationByRelatedPeople,
366 ViewSpecification,
367 )
368-from lp.services.features.testing import FeatureFixture
369 from lp.services.propertycache import get_property_cache
370 from lp.services.webapp.authorization import check_permission
371 from lp.services.webapp.interaction import ANONYMOUS
372@@ -877,19 +876,3 @@
373 self.assertContentEqual([bug1], spec2.bugs)
374 self.assertContentEqual([spec2], bug1.specifications)
375 self.assertContentEqual([], bug2.specifications)
376-
377-
378-class TestBugLinksWithXRef(TestBugLinks):
379-
380- def setUp(self):
381- super(TestBugLinksWithXRef, self).setUp()
382- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
383-
384-
385-class TestBugLinksWithXRefAndNoOld(TestBugLinks):
386-
387- def setUp(self):
388- super(TestBugLinksWithXRefAndNoOld, self).setUp()
389- self.useFixture(FeatureFixture({
390- 'bugs.xref_buglinks.query': 'true',
391- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
392
393=== modified file 'lib/lp/bugs/model/bug.py'
394--- lib/lp/bugs/model/bug.py 2015-10-01 11:40:45 +0000
395+++ lib/lp/bugs/model/bug.py 2015-10-08 08:52:56 +0000
396@@ -204,7 +204,6 @@
397 sqlvalues,
398 )
399 from lp.services.database.stormbase import StormBase
400-from lp.services.features import getFeatureFlag
401 from lp.services.fields import DuplicateBug
402 from lp.services.helpers import shortlist
403 from lp.services.librarian.interfaces import ILibraryFileAliasSet
404@@ -375,49 +374,29 @@
405
406 @property
407 def cves(self):
408- from lp.bugs.model.bugcve import BugCve
409 from lp.bugs.model.cve import Cve
410- if getFeatureFlag('bugs.xref_buglinks.query'):
411- xref_cve_sequences = [
412- sequence for _, sequence in getUtility(IXRefSet).findFrom(
413- (u'bug', unicode(self.id)), types=[u'cve'])]
414- expr = Cve.sequence.is_in(xref_cve_sequences)
415- else:
416- old_cve_ids = list(IStore(BugCve).find(
417- BugCve,
418- BugCve.bug == self).values(BugCve.cveID))
419- expr = Cve.id.is_in(old_cve_ids)
420+ xref_cve_sequences = [
421+ sequence for _, sequence in getUtility(IXRefSet).findFrom(
422+ (u'bug', unicode(self.id)), types=[u'cve'])]
423+ expr = Cve.sequence.is_in(xref_cve_sequences)
424 return list(sorted(
425 IStore(Cve).find(Cve, expr), key=operator.attrgetter('sequence')))
426
427 @property
428 def questions(self):
429 from lp.answers.model.question import Question
430- from lp.coop.answersbugs.model import QuestionBug
431- if getFeatureFlag('bugs.xref_buglinks.query'):
432- question_ids = [
433- int(id) for _, id in getUtility(IXRefSet).findFrom(
434- (u'bug', unicode(self.id)), types=[u'question'])]
435- else:
436- question_ids = list(IStore(QuestionBug).find(
437- QuestionBug,
438- QuestionBug.bug == self).values(QuestionBug.questionID))
439+ question_ids = [
440+ int(id) for _, id in getUtility(IXRefSet).findFrom(
441+ (u'bug', unicode(self.id)), types=[u'question'])]
442 return list(sorted(
443 bulk.load(Question, question_ids), key=operator.attrgetter('id')))
444
445 @property
446 def specifications(self):
447 from lp.blueprints.model.specification import Specification
448- from lp.blueprints.model.specificationbug import SpecificationBug
449- if getFeatureFlag('bugs.xref_buglinks.query'):
450- spec_ids = [
451- int(id) for _, id in getUtility(IXRefSet).findFrom(
452- (u'bug', unicode(self.id)), types=[u'specification'])]
453- else:
454- spec_ids = list(IStore(SpecificationBug).find(
455- SpecificationBug,
456- SpecificationBug.bug == self).values(
457- SpecificationBug.specificationID))
458+ spec_ids = [
459+ int(id) for _, id in getUtility(IXRefSet).findFrom(
460+ (u'bug', unicode(self.id)), types=[u'specification'])]
461 return list(sorted(
462 bulk.load(Specification, spec_ids), key=operator.attrgetter('id')))
463
464
465=== removed file 'lib/lp/bugs/model/bugcve.py'
466--- lib/lp/bugs/model/bugcve.py 2015-09-28 05:58:10 +0000
467+++ lib/lp/bugs/model/bugcve.py 1970-01-01 00:00:00 +0000
468@@ -1,22 +0,0 @@
469-# Copyright 2009 Canonical Ltd. This software is licensed under the
470-# GNU Affero General Public License version 3 (see the file LICENSE).
471-
472-__metaclass__ = type
473-__all__ = ['BugCve']
474-
475-from sqlobject import ForeignKey
476-
477-from lp.services.database.constants import UTC_NOW
478-from lp.services.database.datetimecol import UtcDateTimeCol
479-from lp.services.database.sqlbase import SQLBase
480-
481-
482-class BugCve(SQLBase):
483- """A table linking bugs and CVE entries."""
484-
485- _table = 'BugCve'
486-
487- # db field names
488- bug = ForeignKey(dbName='bug', foreignKey='Bug', notNull=True)
489- cve = ForeignKey(dbName='cve', foreignKey='Cve', notNull=True)
490- date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
491
492=== modified file 'lib/lp/bugs/model/bugtask.py'
493--- lib/lp/bugs/model/bugtask.py 2015-09-28 08:31:27 +0000
494+++ lib/lp/bugs/model/bugtask.py 2015-10-08 08:52:56 +0000
495@@ -139,7 +139,6 @@
496 SQLBase,
497 sqlvalues,
498 )
499-from lp.services.features import getFeatureFlag
500 from lp.services.helpers import shortlist
501 from lp.services.propertycache import get_property_cache
502 from lp.services.searchbuilder import any
503@@ -879,7 +878,7 @@
504 new_status = BugTaskStatusSearch.INCOMPLETE_WITH_RESPONSE
505
506 self._setStatusDateProperties(self.status, new_status, when=when)
507-
508+
509 def _setStatusDateProperties(self, old_status, new_status, when=None):
510 if old_status == new_status:
511 # No change in the status, so nothing to do.
512@@ -1385,20 +1384,14 @@
513 def getBugTaskBadgeProperties(self, bugtasks):
514 """See `IBugTaskSet`."""
515 # Import locally to avoid circular imports.
516- from lp.blueprints.model.specificationbug import SpecificationBug
517 from lp.bugs.model.bug import Bug
518 from lp.bugs.model.bugbranch import BugBranch
519
520 bug_ids = set(bugtask.bugID for bugtask in bugtasks)
521- if getFeatureFlag('bugs.xref_buglinks.query'):
522- bug_ids_with_specifications = set(
523- int(id) for _, id in getUtility(IXRefSet).findFromMany(
524- [(u'bug', unicode(bug_id)) for bug_id in bug_ids],
525- types=[u'specification']).keys())
526- else:
527- bug_ids_with_specifications = set(IStore(SpecificationBug).find(
528- SpecificationBug.bugID,
529- SpecificationBug.bugID.is_in(bug_ids)))
530+ bug_ids_with_specifications = set(
531+ int(id) for _, id in getUtility(IXRefSet).findFromMany(
532+ [(u'bug', unicode(bug_id)) for bug_id in bug_ids],
533+ types=[u'specification']).keys())
534 bug_ids_with_branches = set(IStore(BugBranch).find(
535 BugBranch.bugID, BugBranch.bugID.is_in(bug_ids)))
536 # Badging looks up milestones too : eager load into the storm cache.
537
538=== modified file 'lib/lp/bugs/model/bugtasksearch.py'
539--- lib/lp/bugs/model/bugtasksearch.py 2015-09-28 12:35:42 +0000
540+++ lib/lp/bugs/model/bugtasksearch.py 2015-10-08 08:52:56 +0000
541@@ -39,7 +39,6 @@
542
543 from lp.app.enums import PUBLIC_INFORMATION_TYPES
544 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
545-from lp.blueprints.model.specificationbug import SpecificationBug
546 from lp.bugs.errors import InvalidSearchParameters
547 from lp.bugs.interfaces.bugattachment import BugAttachmentType
548 from lp.bugs.interfaces.bugnomination import BugNominationStatus
549@@ -60,7 +59,6 @@
550 )
551 from lp.bugs.model.bugattachment import BugAttachment
552 from lp.bugs.model.bugbranch import BugBranch
553-from lp.bugs.model.bugcve import BugCve
554 from lp.bugs.model.bugmessage import BugMessage
555 from lp.bugs.model.bugnomination import BugNomination
556 from lp.bugs.model.bugsubscription import BugSubscription
557@@ -95,7 +93,6 @@
558 rank_by_fti,
559 Unnest,
560 )
561-from lp.services.features import getFeatureFlag
562 from lp.services.propertycache import get_property_cache
563 from lp.services.searchbuilder import (
564 all,
565@@ -423,18 +420,13 @@
566 BugTaskFlat.productseries == None))
567
568 if params.has_cve:
569- if getFeatureFlag('bugs.xref_buglinks.query'):
570- where = [
571- XRef.from_type == u'bug',
572- XRef.from_id_int == BugTaskFlat.bug_id,
573- XRef.to_type == u'cve',
574- ]
575- extra_clauses.append(Exists(Select(
576- 1, tables=[XRef], where=And(*where))))
577- else:
578- extra_clauses.append(
579- BugTaskFlat.bug_id.is_in(
580- Select(BugCve.bugID, tables=[BugCve])))
581+ where = [
582+ XRef.from_type == u'bug',
583+ XRef.from_id_int == BugTaskFlat.bug_id,
584+ XRef.to_type == u'cve',
585+ ]
586+ extra_clauses.append(Exists(Select(
587+ 1, tables=[XRef], where=And(*where))))
588
589 if params.attachmenttype is not None:
590 if params.attachmenttype == BugAttachmentType.PATCH:
591@@ -1024,26 +1016,17 @@
592 linked_blueprints = params.linked_blueprints
593
594 def make_clause(blueprints=None):
595- if getFeatureFlag('bugs.xref_buglinks.query'):
596- where = [
597- XRef.from_type == u'bug',
598- XRef.from_id_int == BugTaskFlat.bug_id,
599- XRef.to_type == u'specification',
600- ]
601- if blueprints is not None:
602- where.append(
603- search_value_to_storm_where_condition(
604- XRef.to_id_int, blueprints))
605- return Exists(Select(
606- 1, tables=[XRef], where=And(*where)))
607- else:
608- where = [SpecificationBug.bugID == BugTaskFlat.bug_id]
609- if blueprints is not None:
610- where.append(
611- search_value_to_storm_where_condition(
612- SpecificationBug.specificationID, blueprints))
613- return Exists(Select(
614- 1, tables=[SpecificationBug], where=And(*where)))
615+ where = [
616+ XRef.from_type == u'bug',
617+ XRef.from_id_int == BugTaskFlat.bug_id,
618+ XRef.to_type == u'specification',
619+ ]
620+ if blueprints is not None:
621+ where.append(
622+ search_value_to_storm_where_condition(
623+ XRef.to_id_int, blueprints))
624+ return Exists(Select(
625+ 1, tables=[XRef], where=And(*where)))
626
627 if linked_blueprints is None:
628 return None
629
630=== modified file 'lib/lp/bugs/model/cve.py'
631--- lib/lp/bugs/model/cve.py 2015-09-28 10:52:21 +0000
632+++ lib/lp/bugs/model/cve.py 2015-10-08 08:52:56 +0000
633@@ -31,7 +31,6 @@
634 ICveSet,
635 )
636 from lp.bugs.model.bug import Bug
637-from lp.bugs.model.bugcve import BugCve
638 from lp.bugs.model.buglinktarget import BugLinkTargetMixin
639 from lp.bugs.model.cvereference import CveReference
640 from lp.services.database import bulk
641@@ -41,7 +40,6 @@
642 from lp.services.database.interfaces import IStore
643 from lp.services.database.sqlbase import SQLBase
644 from lp.services.database.stormexpr import fti_search
645-from lp.services.features import getFeatureFlag
646 from lp.services.xref.interfaces import IXRefSet
647 from lp.services.xref.model import XRef
648
649@@ -77,14 +75,9 @@
650
651 @property
652 def bugs(self):
653- if getFeatureFlag('bugs.xref_buglinks.query'):
654- bug_ids = [
655- int(id) for _, id in getUtility(IXRefSet).findFrom(
656- (u'cve', self.sequence), types=[u'bug'])]
657- else:
658- bug_ids = list(IStore(BugCve).find(
659- BugCve,
660- BugCve.cve == self).values(BugCve.bugID))
661+ bug_ids = [
662+ int(id) for _, id in getUtility(IXRefSet).findFrom(
663+ (u'cve', self.sequence), types=[u'bug'])]
664 return list(sorted(
665 bulk.load(Bug, bug_ids), key=operator.attrgetter('id')))
666
667@@ -100,16 +93,12 @@
668
669 def createBugLink(self, bug):
670 """See BugLinkTargetMixin."""
671- if not getFeatureFlag('bugs.xref_buglinks.write_old.disabled'):
672- BugCve(cve=self, bug=bug)
673 # XXX: Should set creator.
674 getUtility(IXRefSet).create(
675 {(u'cve', self.sequence): {(u'bug', unicode(bug.id)): {}}})
676
677 def deleteBugLink(self, bug):
678 """See BugLinkTargetMixin."""
679- if not getFeatureFlag('bugs.xref_buglinks.write_old.disabled'):
680- Store.of(self).find(BugCve, cve=self, bug=bug).remove()
681 getUtility(IXRefSet).delete(
682 {(u'cve', self.sequence): [(u'bug', unicode(bug.id))]})
683
684@@ -202,27 +191,12 @@
685 return []
686 store = Store.of(bugtasks[0])
687
688- if getFeatureFlag('bugs.xref_buglinks.query'):
689- xrefs = getUtility(IXRefSet).findFromMany(
690- [(u'bug', unicode(bug.id)) for bug in bugs], types=[u'cve'])
691- bugcve_ids = set()
692- for bug_key in xrefs:
693- for cve_key in xrefs[bug_key]:
694- bugcve_ids.add((int(bug_key[1]), cve_key[1]))
695- else:
696- # Do not use BugCve instances: Storm may need a very long time
697- # to look up the bugs and CVEs referenced by a BugCve instance
698- # when the +cve view of a distroseries is rendered: There may
699- # be a few thousand (bug, CVE) tuples, while the number of bugs
700- # and CVEs is in the order of hundred. It is much more efficient
701- # to retrieve just (Bug.id, Cve.sequence) from the BugCve
702- # table and to map this to (Bug, CVE) here, instead of
703- # letting Storm look up the CVE and bug for a BugCve
704- # instance, even if bugs and CVEs are bulk loaded.
705- bug_ids = [bug.id for bug in bugs]
706- bugcve_ids = store.find(
707- (BugCve.bugID, Cve.sequence),
708- Cve.id == BugCve.cveID, In(BugCve.bugID, bug_ids))
709+ xrefs = getUtility(IXRefSet).findFromMany(
710+ [(u'bug', unicode(bug.id)) for bug in bugs], types=[u'cve'])
711+ bugcve_ids = set()
712+ for bug_key in xrefs:
713+ for cve_key in xrefs[bug_key]:
714+ bugcve_ids.add((int(bug_key[1]), cve_key[1]))
715
716 bugcve_ids = list(sorted(bugcve_ids))
717
718@@ -241,8 +215,5 @@
719
720 def getBugCveCount(self):
721 """See ICveSet."""
722- if getFeatureFlag('bugs.xref_buglinks.query'):
723- return IStore(XRef).find(
724- XRef, XRef.from_type == u'bug', XRef.to_type == u'cve').count()
725- else:
726- return BugCve.select().count()
727+ return IStore(XRef).find(
728+ XRef, XRef.from_type == u'bug', XRef.to_type == u'cve').count()
729
730=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
731--- lib/lp/bugs/model/tests/test_bugtask.py 2015-10-01 17:32:41 +0000
732+++ lib/lp/bugs/model/tests/test_bugtask.py 2015-10-08 08:52:56 +0000
733@@ -523,22 +523,6 @@
734 ])
735
736
737-class TestBugTaskBadgesWithXRef(TestBugTaskBadges):
738-
739- def setUp(self):
740- super(TestBugTaskBadges, self).setUp()
741- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
742-
743-
744-class TestBugTaskBadgesWithXRefAndNoOld(TestBugTaskBadges):
745-
746- def setUp(self):
747- super(TestBugTaskBadges, self).setUp()
748- self.useFixture(FeatureFixture({
749- 'bugs.xref_buglinks.query': 'true',
750- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
751-
752-
753 class TestBugTaskPrivacy(TestCaseWithFactory):
754 """Verify that the bug is either private or public.
755
756
757=== modified file 'lib/lp/bugs/model/tests/test_bugtasksearch.py'
758--- lib/lp/bugs/model/tests/test_bugtasksearch.py 2015-09-28 12:35:42 +0000
759+++ lib/lp/bugs/model/tests/test_bugtasksearch.py 2015-10-08 08:52:56 +0000
760@@ -67,7 +67,6 @@
761 from lp.registry.model.person import Person
762 from lp.services.database.interfaces import IStore
763 from lp.services.database.sqlbase import convert_storm_clause_to_string
764-from lp.services.features.testing import FeatureFixture
765 from lp.services.searchbuilder import (
766 all,
767 any,
768@@ -420,16 +419,6 @@
769 BugBlueprintSearch.BUGS_WITHOUT_BLUEPRINTS))
770 self.assertSearchFinds(params, self.bugtasks[1:])
771
772- def test_blueprints_linked_with_xref(self):
773- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
774- self.test_blueprints_linked()
775-
776- def test_blueprints_linked_with_xref_and_no_old(self):
777- self.useFixture(FeatureFixture({
778- 'bugs.xref_buglinks.query': 'true',
779- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
780- self.test_blueprints_linked()
781-
782 def test_limit_search_to_one_bug(self):
783 # Search results can be limited to a given bug.
784 params = self.getBugTaskSearchParams(
785@@ -503,16 +492,6 @@
786 params = self.getBugTaskSearchParams(user=None, has_cve=True)
787 self.assertSearchFinds(params, self.bugtasks[:1])
788
789- def test_has_cve_with_xref(self):
790- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
791- self.test_has_cve()
792-
793- def test_has_cve_with_xref_and_no_old(self):
794- self.useFixture(FeatureFixture({
795- 'bugs.xref_buglinks.query': 'true',
796- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
797- self.test_has_cve()
798-
799 def test_sort_by_milestone_name(self):
800 expected = self.setUpMilestoneSorting()
801 params = self.getBugTaskSearchParams(
802
803=== modified file 'lib/lp/bugs/tests/test_cve.py'
804--- lib/lp/bugs/tests/test_cve.py 2015-09-28 09:44:29 +0000
805+++ lib/lp/bugs/tests/test_cve.py 2015-10-08 08:52:56 +0000
806@@ -7,7 +7,6 @@
807
808 from lp.bugs.interfaces.bugtasksearch import BugTaskSearchParams
809 from lp.bugs.interfaces.cve import ICveSet
810-from lp.services.features.testing import FeatureFixture
811 from lp.testing import (
812 login_person,
813 person_logged_in,
814@@ -99,22 +98,6 @@
815 self.assertEqual(base, getUtility(ICveSet).getBugCveCount())
816
817
818-class TestCveSetWithXRef(TestCveSet):
819-
820- def setUp(self):
821- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
822- super(TestCveSetWithXRef, self).setUp()
823-
824-
825-class TestCveSetWithXRefAndNoOld(TestCveSet):
826-
827- def setUp(self):
828- self.useFixture(FeatureFixture({
829- 'bugs.xref_buglinks.query': 'true',
830- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
831- super(TestCveSetWithXRefAndNoOld, self).setUp()
832-
833-
834 class TestBugLinks(TestCaseWithFactory):
835
836 layer = DatabaseFunctionalLayer
837@@ -150,19 +133,3 @@
838 self.assertContentEqual([bug1], cve2.bugs)
839 self.assertContentEqual([cve2], bug1.cves)
840 self.assertContentEqual([], bug2.cves)
841-
842-
843-class TestBugLinksWithXRef(TestBugLinks):
844-
845- def setUp(self):
846- super(TestBugLinksWithXRef, self).setUp()
847- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
848-
849-
850-class TestBugLinksWithXRefAndNoOld(TestBugLinks):
851-
852- def setUp(self):
853- super(TestBugLinksWithXRefAndNoOld, self).setUp()
854- self.useFixture(FeatureFixture({
855- 'bugs.xref_buglinks.query': 'true',
856- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
857
858=== removed file 'lib/lp/coop/answersbugs/model.py'
859--- lib/lp/coop/answersbugs/model.py 2015-09-28 05:58:10 +0000
860+++ lib/lp/coop/answersbugs/model.py 1970-01-01 00:00:00 +0000
861@@ -1,25 +0,0 @@
862-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
863-# GNU Affero General Public License version 3 (see the file LICENSE).
864-
865-"""SQLBase implementation of IQuestionBug."""
866-
867-__metaclass__ = type
868-
869-__all__ = ['QuestionBug']
870-
871-from sqlobject import ForeignKey
872-
873-from lp.services.database.constants import UTC_NOW
874-from lp.services.database.datetimecol import UtcDateTimeCol
875-from lp.services.database.sqlbase import SQLBase
876-
877-
878-class QuestionBug(SQLBase):
879- """A link between a question and a bug."""
880-
881- _table = 'QuestionBug'
882-
883- question = ForeignKey(
884- dbName='question', foreignKey='Question', notNull=True)
885- bug = ForeignKey(dbName='bug', foreignKey='Bug', notNull=True)
886- date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
887
888=== modified file 'lib/lp/coop/answersbugs/tests/test_questionbug.py'
889--- lib/lp/coop/answersbugs/tests/test_questionbug.py 2015-10-01 01:42:13 +0000
890+++ lib/lp/coop/answersbugs/tests/test_questionbug.py 2015-10-08 08:52:56 +0000
891@@ -1,7 +1,6 @@
892 # Copyright 2015 Canonical Ltd. This software is licensed under the
893 # GNU Affero General Public License version 3 (see the file LICENSE).
894
895-from lp.services.features.testing import FeatureFixture
896 from lp.testing import (
897 login_person,
898 TestCaseWithFactory,
899@@ -101,19 +100,3 @@
900 self.assertFalse(bug.isSubscribed(question.owner))
901 question.unlinkBug(bug)
902 self.assertFalse(bug.isSubscribed(question.owner))
903-
904-
905-class TestQuestionBugLinksWithXRef(TestQuestionBugLinks):
906-
907- def setUp(self):
908- super(TestQuestionBugLinksWithXRef, self).setUp()
909- self.useFixture(FeatureFixture({'bugs.xref_buglinks.query': 'true'}))
910-
911-
912-class TestQuestionBugLinksWithXRefAndNoOld(TestQuestionBugLinks):
913-
914- def setUp(self):
915- super(TestQuestionBugLinksWithXRefAndNoOld, self).setUp()
916- self.useFixture(FeatureFixture({
917- 'bugs.xref_buglinks.query': 'true',
918- 'bugs.xref_buglinks.write_old.disabled': 'true'}))
919
920=== modified file 'lib/lp/scripts/garbo.py'
921--- lib/lp/scripts/garbo.py 2015-10-01 01:33:13 +0000
922+++ lib/lp/scripts/garbo.py 2015-10-08 08:52:56 +0000
923@@ -12,7 +12,6 @@
924 'save_garbo_job_state',
925 ]
926
927-from collections import defaultdict
928 from datetime import (
929 datetime,
930 timedelta,
931@@ -82,7 +81,6 @@
932 from lp.services.database.bulk import (
933 create,
934 dbify_value,
935- load_related,
936 )
937 from lp.services.database.constants import UTC_NOW
938 from lp.services.database.interfaces import IMasterStore
939@@ -1680,66 +1678,6 @@
940 transaction.abort()
941
942
943-class BugXRefMigrator(TunableLoop):
944- """Creates an XRef record for each former IBugLink."""
945-
946- maximum_chunk_size = 5000
947-
948- def __init__(self, log, abort_time=None):
949- super(BugXRefMigrator, self).__init__(log, abort_time)
950- self.start_at = 1
951- self.store = IMasterStore(Bug)
952-
953- def findBugs(self):
954- if not getFeatureFlag('bugs.xref_buglinks.garbo.enabled'):
955- return EmptyResultSet()
956- return self.store.find(
957- Bug, Bug.id >= self.start_at).order_by(Bug.id)
958-
959- def isDone(self):
960- return self.findBugs().is_empty()
961-
962- def __call__(self, chunk_size):
963- # Grab a chunk of Bug IDs.
964- # Find all QuestionBugs, SpecificationBugs and BugCves for each
965- # of those bugs.
966- # Compose a list of link IDs that should exist.
967- # Perform a bulk XRef find for all of those.
968- # Create any missing.
969- from lp.blueprints.model.specificationbug import SpecificationBug
970- from lp.bugs.model.bugcve import BugCve
971- from lp.bugs.model.cve import Cve
972- from lp.coop.answersbugs.model import QuestionBug
973- from lp.services.xref.interfaces import IXRefSet
974- bug_ids = list(self.findBugs()[:chunk_size].values(Bug.id))
975- qbs = list(self.store.find(
976- QuestionBug, QuestionBug.bugID.is_in(bug_ids)))
977- sbs = list(self.store.find(
978- SpecificationBug, SpecificationBug.bugID.is_in(bug_ids)))
979- bcs = list(self.store.find(BugCve, BugCve.bugID.is_in(bug_ids)))
980- wanted = defaultdict(dict)
981- for qb in qbs:
982- wanted[(u'bug', unicode(qb.bugID))][
983- (u'question', unicode(qb.questionID))] = {
984- 'date_created': qb.date_created}
985- for sb in sbs:
986- wanted[(u'bug', unicode(sb.bugID))][
987- (u'specification', unicode(sb.specificationID))] = {}
988- load_related(Cve, bcs, ['cveID'])
989- for bc in bcs:
990- wanted[(u'bug', unicode(bc.bugID))][
991- (u'cve', unicode(bc.cve.sequence))] = {}
992- existing = getUtility(IXRefSet).findFromMany(wanted.keys())
993- needed = {
994- bug: {
995- other: meta for other, meta in others.iteritems()
996- if other not in existing.get(bug, {})}
997- for bug, others in wanted.iteritems() if others}
998- getUtility(IXRefSet).create(needed)
999- self.start_at = bug_ids[-1] + 1
1000- transaction.commit()
1001-
1002-
1003 class FrequentDatabaseGarbageCollector(BaseDatabaseGarbageCollector):
1004 """Run every 5 minutes.
1005
1006@@ -1773,7 +1711,6 @@
1007 tunable_loops = [
1008 BugHeatUpdater,
1009 BugWatchScheduler,
1010- BugXRefMigrator,
1011 DuplicateSessionPruner,
1012 RevisionCachePruner,
1013 UnusedSessionPruner,
1014
1015=== modified file 'lib/lp/scripts/tests/test_garbo.py'
1016--- lib/lp/scripts/tests/test_garbo.py 2015-09-28 05:58:10 +0000
1017+++ lib/lp/scripts/tests/test_garbo.py 2015-10-08 08:52:56 +0000
1018@@ -1433,94 +1433,6 @@
1019 for person in people_enf_true:
1020 _assert_enf_by_person(person, True)
1021
1022- def test_BugXRefMigrator(self):
1023- from testtools.matchers import (
1024- Equals,
1025- Is,
1026- MatchesDict,
1027- Not,
1028- )
1029-
1030- from lp.bugs.model.bug import Bug
1031- from lp.bugs.model.bugcve import BugCve
1032- from lp.blueprints.model.specificationbug import SpecificationBug
1033- from lp.coop.answersbugs.model import QuestionBug
1034- from lp.services.database.interfaces import IStore
1035- from lp.services.xref.interfaces import IXRefSet
1036-
1037- switch_dbuser('testadmin')
1038- self.useFixture(FeatureFixture(
1039- {'bugs.xref_buglinks.garbo.enabled': 'on'}))
1040- store = IStore(Bug)
1041-
1042- # The first bug has a spec and a question.
1043- bug1 = self.factory.makeBug()
1044- spec1 = self.factory.makeSpecification()
1045- sb1 = SpecificationBug(specification=spec1, bug=bug1)
1046- store.add(sb1)
1047- question1 = self.factory.makeQuestion()
1048- qb1 = QuestionBug(question=question1, bug=bug1)
1049- store.add(qb1)
1050-
1051- # A second bug has a question and a CVE.
1052- bug2 = self.factory.makeBug()
1053- question2 = self.factory.makeQuestion()
1054- qb2 = QuestionBug(question=question2, bug=bug2)
1055- store.add(qb2)
1056- cve2 = self.factory.makeCVE(sequence='2099-1234')
1057- bc2 = BugCve(bug=bug2, cve=cve2)
1058- store.add(bc2)
1059-
1060- # Bug the third is all alone.
1061- bug3 = self.factory.makeBug()
1062-
1063- # Bug four has just a spec.
1064- bug4 = self.factory.makeBug()
1065- spec4 = self.factory.makeSpecification()
1066- sb4 = SpecificationBug(specification=spec4, bug=bug4)
1067- store.add(sb4)
1068-
1069- # Initially the new XRef table has no links for the bugs.
1070- self.assertEqual(
1071- {},
1072- getUtility(IXRefSet).findFromMany(
1073- (u'bug', unicode(bug.id)) for bug in (bug1, bug2, bug3, bug4)))
1074-
1075- # Garbo fills in links for each QuestionBug, SpecificationBug
1076- # and BugCve.
1077- self.runHourly()
1078- matches_expected = MatchesDict({
1079- (u'bug', unicode(bug1.id)): MatchesDict({
1080- (u'specification', unicode(spec1.id)): MatchesDict({
1081- 'metadata': Is(None), 'creator': Is(None),
1082- 'date_created': Not(Is(None))}),
1083- (u'question', unicode(question1.id)): MatchesDict({
1084- 'metadata': Is(None), 'creator': Is(None),
1085- 'date_created': Equals(qb1.date_created)}),
1086- }),
1087- (u'bug', unicode(bug2.id)): MatchesDict({
1088- (u'question', unicode(question2.id)): MatchesDict({
1089- 'metadata': Is(None), 'creator': Is(None),
1090- 'date_created': Equals(qb2.date_created)}),
1091- (u'cve', cve2.sequence): MatchesDict({
1092- 'metadata': Is(None), 'creator': Is(None),
1093- 'date_created': Not(Is(None))}),
1094- }),
1095- (u'bug', unicode(bug4.id)): MatchesDict({
1096- (u'specification', unicode(spec4.id)): MatchesDict({
1097- 'metadata': Is(None), 'creator': Is(None),
1098- 'date_created': Not(Is(None))}),
1099- }),
1100- })
1101- self.assertThat(
1102- getUtility(IXRefSet).findFromMany(
1103- (u'bug', unicode(bug.id)) for bug in (bug1, bug2, bug3, bug4)),
1104- matches_expected)
1105-
1106- # A second run is harmless.
1107- self.runHourly()
1108-
1109-
1110
1111 class TestGarboTasks(TestCaseWithFactory):
1112 layer = LaunchpadZopelessLayer