launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #07480
[Merge] lp:~wgrant/launchpad/bugtaskflat-by-default into lp:launchpad
William Grant has proposed merging lp:~wgrant/launchpad/bugtaskflat-by-default into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~wgrant/launchpad/bugtaskflat-by-default/+merge/104215
This branch is a fairly straightforward obliteration of the non-BugTaskFlat bug search mechanism. A few query counts needed incrementing to cope with the extra BugTask selection query.
--
https://code.launchpad.net/~wgrant/launchpad/bugtaskflat-by-default/+merge/104215
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/bugtaskflat-by-default into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py 2012-04-27 05:56:48 +0000
+++ lib/lp/bugs/browser/bugtask.py 2012-05-01 07:46:21 +0000
@@ -217,7 +217,7 @@
from lp.bugs.interfaces.bugwatch import BugWatchActivityStatus
from lp.bugs.interfaces.cve import ICveSet
from lp.bugs.interfaces.malone import IMaloneApplication
-from lp.bugs.model.bugtasksearch import unflat_orderby_expression
+from lp.bugs.model.bugtasksearch import orderby_expression
from lp.code.interfaces.branchcollection import IAllBranches
from lp.layers import FeedsLayer
from lp.registry.enums import InformationType
@@ -2802,7 +2802,7 @@
orderby_col = orderby_col[1:]
try:
- unflat_orderby_expression[orderby_col]
+ orderby_expression[orderby_col]
except KeyError:
raise UnexpectedFormData(
"Unknown sort column '%s'" % orderby_col)
=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
--- lib/lp/bugs/browser/tests/test_bugtask.py 2012-04-18 03:56:54 +0000
+++ lib/lp/bugs/browser/tests/test_bugtask.py 2012-05-01 07:46:21 +0000
@@ -52,7 +52,7 @@
IBugTask,
IBugTaskSet,
)
-from lp.bugs.model.bugtasksearch import unflat_orderby_expression
+from lp.bugs.model.bugtasksearch import orderby_expression
from lp.layers import (
FeedsLayer,
setFirstLayer,
@@ -139,7 +139,7 @@
self.getUserBrowser(url, person_no_teams)
# This may seem large: it is; there is easily another 30% fat in
# there.
- self.assertThat(recorder, HasQueryCount(LessThan(86)))
+ self.assertThat(recorder, HasQueryCount(LessThan(88)))
count_with_no_teams = recorder.count
# count with many teams
self.invalidate_caches(task)
@@ -155,7 +155,7 @@
def test_rendered_query_counts_constant_with_attachments(self):
with celebrity_logged_in('admin'):
browses_under_limit = BrowsesWithQueryLimit(
- 89, self.factory.makePerson())
+ 91, self.factory.makePerson())
# First test with a single attachment.
task = self.factory.makeBugTask()
@@ -200,7 +200,7 @@
self.invalidate_caches(task)
self.getUserBrowser(url, owner)
# At least 20 of these should be removed.
- self.assertThat(recorder, HasQueryCount(LessThan(108)))
+ self.assertThat(recorder, HasQueryCount(LessThan(110)))
count_with_no_branches = recorder.count
for sp in sourcepackages:
self.makeLinkedBranchMergeProposal(sp, bug, owner)
@@ -2325,7 +2325,7 @@
cache = IJSONRequestCache(view.request)
json_sort_keys = cache.objects['sort_keys']
json_sort_keys = set(key[0] for key in json_sort_keys)
- valid_keys = set(unflat_orderby_expression.keys())
+ valid_keys = set(orderby_expression.keys())
self.assertEqual(
valid_keys, json_sort_keys,
"Existing sort order values not available in JSON cache: %r; "
=== modified file 'lib/lp/bugs/model/bugtasksearch.py'
--- lib/lp/bugs/model/bugtasksearch.py 2012-04-27 06:30:48 +0000
+++ lib/lp/bugs/model/bugtasksearch.py 2012-05-01 07:46:21 +0000
@@ -5,7 +5,7 @@
__all__ = [
'get_bug_privacy_filter',
- 'unflat_orderby_expression',
+ 'orderby_expression',
'search_bugs',
]
@@ -81,7 +81,6 @@
Array,
NullCount,
)
-from lp.services.features import getFeatureFlag
from lp.services.propertycache import get_property_cache
from lp.services.searchbuilder import (
all,
@@ -94,37 +93,7 @@
from lp.soyuz.model.publishing import SourcePackagePublishingHistory
-# This abstracts most of the columns involved in search so we can switch
-# to/from BugTaskFlat easily.
-unflat_cols = {
- 'Bug.id': Bug.id,
- 'Bug.duplicateof': Bug.duplicateof,
- 'Bug.owner': Bug.owner,
- 'Bug.date_last_updated': Bug.date_last_updated,
- 'BugTask.id': BugTask.id,
- 'BugTask.bug': BugTask.bug,
- 'BugTask.bugID': BugTask.bugID,
- 'BugTask.importance': BugTask.importance,
- 'BugTask.product': BugTask.product,
- 'BugTask.productID': BugTask.productID,
- 'BugTask.productseries': BugTask.productseries,
- 'BugTask.productseriesID': BugTask.productseriesID,
- 'BugTask.distribution': BugTask.distribution,
- 'BugTask.distributionID': BugTask.distributionID,
- 'BugTask.distroseries': BugTask.distroseries,
- 'BugTask.distroseriesID': BugTask.distroseriesID,
- 'BugTask.sourcepackagename': BugTask.sourcepackagename,
- 'BugTask.sourcepackagenameID': BugTask.sourcepackagenameID,
- 'BugTask.milestone': BugTask.milestone,
- 'BugTask.milestoneID': BugTask.milestoneID,
- 'BugTask.assignee': BugTask.assignee,
- 'BugTask.owner': BugTask.owner,
- 'BugTask.date_closed': BugTask.date_closed,
- 'BugTask.datecreated': BugTask.datecreated,
- 'BugTask._status': BugTask._status,
- }
-
-flat_cols = {
+cols = {
'Bug.id': BugTaskFlat.bug_id,
'Bug.duplicateof': BugTaskFlat.duplicateof,
'Bug.owner': BugTaskFlat.bug_owner,
@@ -153,90 +122,12 @@
}
-bug_join = (Bug, Join(Bug, BugTask.bug == Bug.id))
Assignee = ClassAlias(Person)
Reporter = ClassAlias(Person)
-unflat_orderby_expression = {
- "task": (BugTask.id, []),
- "id": (BugTask.bugID, []),
- "importance": (BugTask.importance, []),
- # TODO: sort by their name?
- "assignee": (
- Assignee.name,
- [
- (Assignee,
- LeftJoin(Assignee, BugTask.assignee == Assignee.id))
- ]),
- "targetname": (BugTask.targetnamecache, []),
- "status": (BugTask._status, []),
- "title": (Bug.title, [bug_join]),
- "milestone": (BugTask.milestoneID, []),
- "dateassigned": (BugTask.date_assigned, []),
- "datecreated": (BugTask.datecreated, []),
- "date_last_updated": (Bug.date_last_updated, [bug_join]),
- "date_closed": (BugTask.date_closed, []),
- "number_of_duplicates": (Bug.number_of_duplicates, [bug_join]),
- "message_count": (Bug.message_count, [bug_join]),
- "users_affected_count": (Bug.users_affected_count, [bug_join]),
- "heat": (BugTask.heat, []),
- "latest_patch_uploaded": (Bug.latest_patch_uploaded, [bug_join]),
- "milestone_name": (
- Milestone.name,
- [
- (Milestone,
- LeftJoin(Milestone,
- BugTask.milestone == Milestone.id))
- ]),
- "reporter": (
- Reporter.name,
- [
- bug_join,
- (Reporter, Join(Reporter, Bug.owner == Reporter.id))
- ]),
- "tag": (
- BugTag.tag,
- [
- bug_join,
- (BugTag,
- LeftJoin(
- BugTag,
- BugTag.bug == Bug.id and
- # We want at most one tag per bug. Select the
- # tag that comes first in alphabetic order.
- BugTag.id == Select(
- BugTag.id, tables=[BugTag],
- where=(BugTag.bugID == Bug.id),
- order_by=BugTag.tag, limit=1))),
- ]
- ),
- "specification": (
- Specification.name,
- [
- bug_join,
- (Specification,
- LeftJoin(
- Specification,
- # We want at most one specification per bug.
- # Select the specification that comes first
- # in alphabetic order.
- Specification.id == Select(
- Specification.id,
- tables=[
- SpecificationBug,
- Join(
- Specification,
- Specification.id ==
- SpecificationBug.specificationID)],
- where=(SpecificationBug.bugID == Bug.id),
- order_by=Specification.name, limit=1))),
- ]
- ),
- }
-
-flat_bug_join = (Bug, Join(Bug, Bug.id == BugTaskFlat.bug_id))
-flat_bugtask_join = (
+bug_join = (Bug, Join(Bug, Bug.id == BugTaskFlat.bug_id))
+bugtask_join = (
BugTask, Join(BugTask, BugTask.id == BugTaskFlat.bugtask_id))
-flat_orderby_expression = {
+orderby_expression = {
"task": (BugTaskFlat.bugtask_id, []),
"id": (BugTaskFlat.bug_id, []),
"importance": (BugTaskFlat.importance, []),
@@ -247,19 +138,19 @@
(Assignee,
LeftJoin(Assignee, BugTaskFlat.assignee == Assignee.id))
]),
- "targetname": (BugTask.targetnamecache, [flat_bugtask_join]),
+ "targetname": (BugTask.targetnamecache, [bugtask_join]),
"status": (BugTaskFlat.status, []),
- "title": (Bug.title, [flat_bug_join]),
+ "title": (Bug.title, [bug_join]),
"milestone": (BugTaskFlat.milestone_id, []),
- "dateassigned": (BugTask.date_assigned, [flat_bugtask_join]),
+ "dateassigned": (BugTask.date_assigned, [bugtask_join]),
"datecreated": (BugTaskFlat.datecreated, []),
"date_last_updated": (BugTaskFlat.date_last_updated, []),
- "date_closed": (BugTask.date_closed, [flat_bugtask_join]),
- "number_of_duplicates": (Bug.number_of_duplicates, [flat_bug_join]),
- "message_count": (Bug.message_count, [flat_bug_join]),
- "users_affected_count": (Bug.users_affected_count, [flat_bug_join]),
+ "date_closed": (BugTask.date_closed, [bugtask_join]),
+ "number_of_duplicates": (Bug.number_of_duplicates, [bug_join]),
+ "message_count": (Bug.message_count, [bug_join]),
+ "users_affected_count": (Bug.users_affected_count, [bug_join]),
"heat": (BugTaskFlat.heat, []),
- "latest_patch_uploaded": (Bug.latest_patch_uploaded, [flat_bug_join]),
+ "latest_patch_uploaded": (Bug.latest_patch_uploaded, [bug_join]),
"milestone_name": (
Milestone.name,
[
@@ -348,38 +239,29 @@
respected.
:param just_bug_ids: Return a ResultSet of bug IDs instead of BugTasks.
"""
- use_flat = bool(getFeatureFlag('bugs.bugtaskflat.search.enabled'))
-
store = IStore(BugTask)
- orderby_expression, orderby_joins = _process_order_by(
- alternatives[0], use_flat)
+ orderby_expression, orderby_joins = _process_order_by(alternatives[0])
decorators = []
- # If we are to use BugTaskFlat, we just return the ID. The
- # DecoratedResultSet will turn it into the actual BugTask.
- # If we're not using BugTaskFlat yet, we should still return
- # the BugTask directly.
- if use_flat:
- start = BugTaskFlat
- if just_bug_ids:
- want = BugTaskFlat.bug_id
- else:
- want = BugTaskFlat.bugtask_id
- decorators.append(lambda id: IStore(BugTask).get(BugTask, id))
- orig_pre_iter_hook = pre_iter_hook
-
- def pre_iter_hook(rows):
- rows = load(BugTask, rows)
- if orig_pre_iter_hook:
- orig_pre_iter_hook(rows)
+ # Normally we just return the ID -- the DecoratedResultSet will turn
+ # it into the actual BugTask. But the caller can also request to
+ # just get the bug IDs back, in which case we don't use DRS.
+ start = BugTaskFlat
+ if just_bug_ids:
+ want = BugTaskFlat.bug_id
else:
- start = BugTask
- want = BugTask.bugID if just_bug_ids else BugTask
+ want = BugTaskFlat.bugtask_id
+ decorators.append(lambda id: IStore(BugTask).get(BugTask, id))
+ orig_pre_iter_hook = pre_iter_hook
+
+ def pre_iter_hook(rows):
+ rows = load(BugTask, rows)
+ if orig_pre_iter_hook:
+ orig_pre_iter_hook(rows)
if len(alternatives) == 1:
[query, clauseTables, bugtask_decorator, join_tables,
- has_duplicate_results, with_clause] = _build_query(
- alternatives[0], use_flat)
+ has_duplicate_results, with_clause] = _build_query(alternatives[0])
if with_clause:
store = store.with_(with_clause)
decorators.append(bugtask_decorator)
@@ -387,10 +269,10 @@
if has_duplicate_results:
origin = _build_origin(join_tables, clauseTables, start)
outer_origin = _build_origin(orderby_joins, [], start)
- want_inner = BugTaskFlat.bugtask_id if use_flat else BugTask.id
- subquery = Select(want_inner, where=query, tables=origin)
+ subquery = Select(
+ BugTaskFlat.bugtask_id, where=query, tables=origin)
result = store.using(*outer_origin).find(
- want, In(want_inner, subquery))
+ want, In(BugTaskFlat.bugtask_id, subquery))
else:
origin = _build_origin(
join_tables + orderby_joins, clauseTables, start)
@@ -400,14 +282,12 @@
for params in alternatives:
[query, clauseTables, decorator, join_tables,
- has_duplicate_results, with_clause] = _build_query(
- params, use_flat)
+ has_duplicate_results, with_clause] = _build_query(params)
origin = _build_origin(join_tables, clauseTables, start)
localstore = store
if with_clause:
localstore = store.with_(with_clause)
- want_inner = BugTaskFlat if use_flat else BugTask
- next_result = localstore.using(*origin).find((want_inner,), query)
+ next_result = localstore.using(*origin).find(BugTaskFlat, query)
results.append(next_result)
# NB: assumes the decorators are all compatible.
# This may need revisiting if e.g. searches on behalf of different
@@ -416,10 +296,7 @@
resultset = reduce(lambda l, r: l.union(r), results)
origin = _build_origin(
- orderby_joins, [],
- Alias(
- resultset._get_select(),
- "BugTaskFlat" if use_flat else "BugTask"))
+ orderby_joins, [], Alias(resultset._get_select(), "BugTaskFlat"))
result = store.using(*origin).find(want)
result.order_by(orderby_expression)
@@ -457,7 +334,7 @@
return origin
-def _build_query(params, use_flat):
+def _build_query(params):
"""Build and return an SQL query with the given parameters.
Also return the clauseTables and orderBy for the generated query.
@@ -466,16 +343,10 @@
decorator to call on each returned row.
"""
params = _require_params(params)
- cols = flat_cols if use_flat else unflat_cols
- if use_flat:
- extra_clauses = []
- clauseTables = []
- join_tables = []
- else:
- extra_clauses = [Bug.id == BugTask.bugID]
- clauseTables = [BugTask, Bug]
- join_tables = []
+ extra_clauses = []
+ clauseTables = []
+ join_tables = []
decorators = []
has_duplicate_results = False
@@ -519,8 +390,8 @@
# All the standard args filter on BugTaskFlat, except for
# date_closed which isn't denormalised (yet?).
- if params.date_closed is not None and use_flat:
- join_tables.append(flat_bugtask_join)
+ if params.date_closed is not None:
+ join_tables.append(bugtask_join)
if params.status is not None:
extra_clauses.append(
@@ -607,8 +478,7 @@
if params.attachmenttype is not None:
if params.attachmenttype == BugAttachmentType.PATCH:
extra_clauses.append(Bug.latest_patch_uploaded != None)
- if use_flat:
- join_tables.append(flat_bug_join)
+ join_tables.append(bug_join)
else:
extra_clauses.append(
cols['Bug.id'].is_in(
@@ -618,12 +488,10 @@
BugAttachment.type, params.attachmenttype))))
if params.searchtext:
- extra_clauses.append(_build_search_text_clause(
- params, use_flat=use_flat))
+ extra_clauses.append(_build_search_text_clause(params))
if params.fast_searchtext:
- extra_clauses.append(_build_search_text_clause(
- params, fast=True, use_flat=use_flat))
+ extra_clauses.append(_build_search_text_clause(params, fast=True))
if params.subscriber is not None:
clauseTables.append(BugSubscription)
@@ -855,7 +723,7 @@
Milestone.dateexpected <= dateexpected_before)
clause, decorator = _get_bug_privacy_filter_with_decorator(
- params.user, use_flat=use_flat)
+ params.user, use_flat=True)
if clause:
extra_clauses.append(SQL(clause))
decorators.append(decorator)
@@ -913,7 +781,7 @@
has_duplicate_results, with_clause)
-def _process_order_by(params, use_flat):
+def _process_order_by(params):
"""Process the orderby parameter supplied to search().
This method ensures the sort order will be stable, and converting
@@ -942,34 +810,15 @@
else:
in_unique_context = False
- if use_flat:
- orderby_expression = flat_orderby_expression
- unambiguous_cols = set([
- BugTaskFlat.date_last_updated,
- BugTaskFlat.datecreated,
- BugTaskFlat.bugtask_id,
- Bug.datecreated,
- BugTask.date_assigned,
- ])
- if in_unique_context:
- unambiguous_cols.add(BugTaskFlat.bug)
- else:
- orderby_expression = unflat_orderby_expression
- # Bug.id and BugTask.bugID shouldn't really be here; they're
- # ambiguous in a distribution or distroseries context. They're
- # omitted from the new BugTaskFlat path, but kept in the legacy
- # code in case it affects index selection.
- unambiguous_cols = set([
- Bug.date_last_updated,
- Bug.datecreated,
- Bug.id,
- BugTask.bugID,
- BugTask.date_assigned,
- BugTask.datecreated,
- BugTask.id,
- ])
- if in_unique_context:
- unambiguous_cols.add(BugTask.bug)
+ unambiguous_cols = set([
+ BugTaskFlat.date_last_updated,
+ BugTaskFlat.datecreated,
+ BugTaskFlat.bugtask_id,
+ Bug.datecreated,
+ BugTask.date_assigned,
+ ])
+ if in_unique_context:
+ unambiguous_cols.add(BugTaskFlat.bug)
# Translate orderby keys into corresponding Table.attribute
# strings.
@@ -1006,16 +855,10 @@
orderby_arg.append(order_clause)
if ambiguous:
- if use_flat:
- if in_unique_context:
- disambiguator = BugTaskFlat.bug_id
- else:
- disambiguator = BugTaskFlat.bugtask_id
+ if in_unique_context:
+ disambiguator = BugTaskFlat.bug_id
else:
- if in_unique_context:
- disambiguator = BugTask.bugID
- else:
- disambiguator = BugTask.id
+ disambiguator = BugTaskFlat.bugtask_id
if orderby_arg and not isinstance(orderby_arg[0], Desc):
disambiguator = Desc(disambiguator)
@@ -1033,7 +876,7 @@
return params
-def _build_search_text_clause(params, fast=False, use_flat=False):
+def _build_search_text_clause(params, fast=False):
"""Build the clause for searchtext."""
if fast:
assert params.searchtext is None, (
@@ -1044,14 +887,13 @@
'Cannot use fast_searchtext at the same time as searchtext.')
searchtext = params.searchtext
- col = 'BugTaskFlat.fti' if use_flat else 'Bug.fti'
-
if params.orderby is None:
# Unordered search results aren't useful, so sort by relevance
# instead.
- params.orderby = [SQL("-rank(%s, ftq(?))" % col, params=(searchtext,))]
+ params.orderby = [
+ SQL("-rank(BugTaskFlat.fti, ftq(?))", params=(searchtext,))]
- return SQL("%s @@ ftq(?)" % col, params=(searchtext,))
+ return SQL("BugTaskFlat.fti @@ ftq(?)", params=(searchtext,))
def _build_status_clause(col, status):
=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py 2012-04-18 22:26:33 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py 2012-05-01 07:46:21 +0000
@@ -1014,7 +1014,7 @@
IPerson(person.account, None)
# The should take 2 queries - one for the tasks, one for the related
# products (eager loaded targets).
- has_expected_queries = HasQueryCount(Equals(3))
+ has_expected_queries = HasQueryCount(Equals(4))
# No extra queries should be issued to access a regular attribute
# on the bug that would normally trigger lazy evaluation for security
# checking. Note that the 'id' attribute does not trigger a check.
=== modified file 'lib/lp/bugs/tests/test_bugsearch_conjoined.py'
--- lib/lp/bugs/tests/test_bugsearch_conjoined.py 2012-04-17 22:56:29 +0000
+++ lib/lp/bugs/tests/test_bugsearch_conjoined.py 2012-05-01 07:46:21 +0000
@@ -70,7 +70,7 @@
list(self.bugtask_set.search(self.params))
# 1 query for the tasks, 1 query for the product (target) eager
# loading.
- self.assertThat(recorder, HasQueryCount(Equals(3)))
+ self.assertThat(recorder, HasQueryCount(Equals(4)))
def test_search_results_count_with_other_productseries_tasks(self):
# Test with zero conjoined masters and bugtasks targeted to
@@ -166,7 +166,7 @@
list(self.bugtask_set.search(self.params))
# 1 query for the tasks, 1 query for the product (target) eager
# loading.
- self.assertThat(recorder, HasQueryCount(Equals(3)))
+ self.assertThat(recorder, HasQueryCount(Equals(4)))
def test_search_results_count_with_other_productseries_tasks(self):
# Test with zero conjoined masters and bugtasks targeted to
@@ -278,7 +278,7 @@
Store.of(self.milestone).flush()
with StormStatementRecorder() as recorder:
list(self.bugtask_set.search(self.params))
- self.assertThat(recorder, HasQueryCount(Equals(3)))
+ self.assertThat(recorder, HasQueryCount(Equals(4)))
def test_search_results_count_with_other_productseries_tasks(self):
# Test with zero conjoined masters and bugtasks targeted to
=== modified file 'lib/lp/bugs/tests/test_bugtask_search.py'
--- lib/lp/bugs/tests/test_bugtask_search.py 2012-04-27 06:29:59 +0000
+++ lib/lp/bugs/tests/test_bugtask_search.py 2012-05-01 07:46:21 +0000
@@ -33,7 +33,6 @@
from lp.registry.interfaces.product import IProduct
from lp.registry.interfaces.sourcepackage import ISourcePackage
from lp.services.database.sqlbase import convert_storm_clause_to_string
-from lp.services.features.testing import FeatureFixture
from lp.services.searchbuilder import (
all,
any,
@@ -64,7 +63,7 @@
params.setProduct(distribution)
self.assertEqual(
expected,
- convert_storm_clause_to_string(_process_order_by(params, True)[0]))
+ convert_storm_clause_to_string(_process_order_by(params)[0]))
def test_tiebreaker(self):
# Requests for ambiguous sorts get a disambiguator of BugTask.id
@@ -1630,31 +1629,6 @@
return [bugtask.bug.id for bugtask in expected_bugtasks]
-class UsingFlat:
- """Use BugTaskFlat for searching."""
-
- def setUp(self):
- super(UsingFlat, self).setUp()
- self.useFixture(
- FeatureFixture({'bugs.bugtaskflat.search.enabled': 'on'}))
-
-
-class UsingLegacy:
- """Use Bug and BugTask directly for searching."""
-
- def test_private_bug_in_search_result_assignees(self):
- # Private bugs are included in search results for the assignee.
- with person_logged_in(self.owner):
- self.bugtasks[-1].bug.setPrivate(True, self.owner)
- bugtask = self.bugtasks[-1]
- user = self.factory.makePerson()
- admin = getUtility(IPersonSet).getByEmail('foo.bar@xxxxxxxxxxxxx')
- with person_logged_in(admin):
- bugtask.transitionToAssignee(user)
- params = self.getBugTaskSearchParams(user=user)
- self.assertSearchFinds(params, self.bugtasks)
-
-
class TestMilestoneDueDateFiltering(TestCaseWithFactory):
layer = LaunchpadFunctionalLayer
@@ -1689,33 +1663,27 @@
loader = unittest.TestLoader()
for bug_target_search_type_class in (
PreloadBugtaskTargets, NoPreloadBugtaskTargets, QueryBugIDs):
- for feature_mixin in (UsingLegacy, UsingFlat):
+ class_name = 'Test%s' % bug_target_search_type_class.__name__
+ class_bases = (
+ bug_target_search_type_class, ProductTarget, OnceTests,
+ SearchTestBase, TestCaseWithFactory)
+ test_class = type(class_name, class_bases, {})
+ suite.addTest(loader.loadTestsFromTestCase(test_class))
+
+ for target_mixin in bug_targets_mixins:
class_name = 'Test%s%s' % (
bug_target_search_type_class.__name__,
- feature_mixin.__name__)
- mixins = [bug_target_search_type_class, feature_mixin]
+ target_mixin.__name__)
+ mixins = [
+ target_mixin, bug_target_search_type_class]
class_bases = (
tuple(mixins)
- + (ProductTarget, OnceTests, SearchTestBase,
- TestCaseWithFactory))
+ + (TargetTests, SearchTestBase, TestCaseWithFactory))
+ # Dynamically build a test class from the target mixin class,
+ # from the search type mixin class, from the mixin class
+ # having all tests and from a unit test base class.
test_class = type(class_name, class_bases, {})
+ # Add the new unit test class to the suite.
suite.addTest(loader.loadTestsFromTestCase(test_class))
-
- for target_mixin in bug_targets_mixins:
- class_name = 'Test%s%s%s' % (
- bug_target_search_type_class.__name__,
- target_mixin.__name__,
- feature_mixin.__name__)
- mixins = [
- target_mixin, bug_target_search_type_class, feature_mixin]
- class_bases = (
- tuple(mixins)
- + (TargetTests, SearchTestBase, TestCaseWithFactory))
- # Dynamically build a test class from the target mixin class,
- # from the search type mixin class, from the mixin class
- # having all tests and from a unit test base class.
- test_class = type(class_name, class_bases, {})
- # Add the new unit test class to the suite.
- suite.addTest(loader.loadTestsFromTestCase(test_class))
suite.addTest(loader.loadTestsFromName(__name__))
return suite
=== modified file 'lib/lp/registry/browser/tests/test_milestone.py'
--- lib/lp/registry/browser/tests/test_milestone.py 2012-04-17 22:56:29 +0000
+++ lib/lp/registry/browser/tests/test_milestone.py 2012-05-01 07:46:21 +0000
@@ -282,18 +282,19 @@
def test_bugtasks_queries(self):
# The view.bugtasks attribute will make several queries:
- # 1. Load bugtasks
- # 2. Load bugs.
- # 3. Loads the target (sourcepackagename / product)
- # 4. Load assignees (Person, Account, and EmailAddress).
- # 5. Load links to specifications.
- # 6. Load links to branches.
- # 7. Loads milestones
- # 8. Loads tags
- # 9. All related people
+ # 1. Search for bugtask IDs.
+ # 2. Load bugtasks
+ # 3. Load bugs.
+ # 4. Loads the target (sourcepackagename / product)
+ # 5. Load assignees (Person, Account, and EmailAddress).
+ # 6. Load links to specifications.
+ # 7. Load links to branches.
+ # 8. Loads milestones
+ # 9. Loads tags
+ # 10. All related people
bugtask_count = 10
self.assert_bugtasks_query_count(
- self.milestone, bugtask_count, query_limit=10)
+ self.milestone, bugtask_count, query_limit=11)
def test_milestone_eager_loading(self):
# Verify that the number of queries does not increase with more
@@ -408,17 +409,18 @@
def test_bugtasks_queries(self):
# The view.bugtasks attribute will make several queries:
# 1. For each project in the group load all the dev focus series ids.
- # 2. Load bugtasks.
- # 3. Load bugs.
- # 4. Load assignees (Person, Account, and EmailAddress).
- # 5. Load links to specifications.
- # 6. Load links to branches.
- # 7. Loads milestones.
- # 8. Loads tags.
- # 9. All related people.
+ # 2. Search for bugtask IDs.
+ # 3. Load bugtasks.
+ # 4. Load bugs.
+ # 5. Load assignees (Person, Account, and EmailAddress).
+ # 6. Load links to specifications.
+ # 7. Load links to branches.
+ # 8. Loads milestones.
+ # 9. Loads tags.
+ # 10. All related people.
bugtask_count = 10
self.assert_bugtasks_query_count(
- self.milestone, bugtask_count, query_limit=10)
+ self.milestone, bugtask_count, query_limit=11)
def test_milestone_eager_loading(self):
# Verify that the number of queries does not increase with more
=== modified file 'lib/lp/registry/browser/tests/test_person.py'
--- lib/lp/registry/browser/tests/test_person.py 2012-04-27 16:42:34 +0000
+++ lib/lp/registry/browser/tests/test_person.py 2012-05-01 07:46:21 +0000
@@ -1321,7 +1321,7 @@
Store.of(milestones[0]).invalidate()
with StormStatementRecorder() as recorder:
self.assertEqual(expected, view.getMilestoneWidgetValues())
- self.assertThat(recorder, HasQueryCount(LessThan(5)))
+ self.assertThat(recorder, HasQueryCount(LessThan(6)))
def test_context_description(self):
# view.context_description returns a string that can be used
=== modified file 'lib/lp/registry/tests/test_person.py'
--- lib/lp/registry/tests/test_person.py 2012-04-20 05:00:49 +0000
+++ lib/lp/registry/tests/test_person.py 2012-05-01 07:46:21 +0000
@@ -1450,4 +1450,4 @@
# 9. One to get all sourcepackagenames;
# 10. One to get all distroseries of a bug's distro. (See comment on
# getAssignedBugTasksDueBefore() to understand why it's needed)
- self.assertThat(recorder, HasQueryCount(Equals(11)))
+ self.assertThat(recorder, HasQueryCount(Equals(12)))
=== modified file 'lib/lp/services/features/flags.py'
--- lib/lp/services/features/flags.py 2012-04-23 14:12:48 +0000
+++ lib/lp/services/features/flags.py 2012-05-01 07:46:21 +0000
@@ -63,12 +63,6 @@
'',
'',
'https://bugs.launchpad.net/launchpad/+bug/678090'),
- ('bugs.bugtaskflat.search.enabled',
- 'boolean',
- 'Use BugTaskFlat for bug searches.',
- '',
- '',
- ''),
('bugs.bugtracker_components.enabled',
'boolean',
('Enables the display of bugtracker components.'),
Follow ups