~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/tests/test_bugnomination.py

[r=allenap][bug=874250] Resurrect
 bugnomination-timeout-bug-874250-lazy-heat from the dead.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
__metaclass__ = type
7
7
 
 
8
from itertools import izip
 
9
import re
 
10
 
 
11
from testtools.content import Content, UTF8_TEXT
 
12
from testtools.matchers import (
 
13
    Equals,
 
14
    LessThan,
 
15
    Not,
 
16
    )
 
17
 
 
18
from canonical.database.sqlbase import flush_database_updates
8
19
from canonical.launchpad.ftests import (
9
20
    login,
10
21
    logout,
13
24
from lp.soyuz.interfaces.publishing import PackagePublishingStatus
14
25
from lp.testing import (
15
26
    celebrity_logged_in,
 
27
    person_logged_in,
 
28
    StormStatementRecorder,
16
29
    TestCaseWithFactory,
17
30
    )
 
31
from lp.testing.matchers import HasQueryCount
18
32
 
19
33
 
20
34
class CanBeNominatedForTestMixin:
216
230
        self.assertFalse(nomination.canApprove(self.factory.makePerson()))
217
231
        self.assertTrue(nomination.canApprove(package_perm.person))
218
232
        self.assertTrue(nomination.canApprove(comp_perm.person))
 
233
 
 
234
 
 
235
class TestApprovePerformance(TestCaseWithFactory):
 
236
    """Test the performance of `BugNomination.approve`."""
 
237
 
 
238
    layer = DatabaseFunctionalLayer
 
239
 
 
240
    def check_heat_queries(self, nomination):
 
241
        self.assertFalse(nomination.isApproved())
 
242
        # Statement patterns we're looking for:
 
243
        pattern = "^(SELECT Bug.heat|UPDATE .* max_bug_heat)"
 
244
        matcher = re.compile(pattern , re.DOTALL | re.I).match
 
245
        queries_heat = lambda statement: matcher(statement) is not None
 
246
        with person_logged_in(nomination.target.owner):
 
247
            flush_database_updates()
 
248
            with StormStatementRecorder(queries_heat) as recorder:
 
249
                nomination.approve(nomination.target.owner)
 
250
        # Post-process the recorder to only have heat-related statements.
 
251
        recorder.query_data = [
 
252
            data for statement, data in izip(
 
253
                recorder.statements, recorder.query_data)
 
254
            if queries_heat(statement)]
 
255
        self.addDetail(
 
256
            "query_data", Content(UTF8_TEXT, lambda: [str(recorder)]))
 
257
        # If there isn't at least one update to max_bug_heat it may mean that
 
258
        # this test is no longer relevant.
 
259
        self.assertThat(recorder, HasQueryCount(Not(Equals(0))))
 
260
        # At present there are two updates to max_bug_heat because
 
261
        # recalculateBugHeatCache is called twice, and, even though it is
 
262
        # lazily evaluated, there are both explicit and implicit flushes in
 
263
        # bugtask subscriber code.
 
264
        self.assertThat(recorder, HasQueryCount(LessThan(3)))
 
265
 
 
266
    def test_heat_queries_for_productseries(self):
 
267
        # The number of heat-related queries when approving a product series
 
268
        # nomination is as low as reasonably possible.
 
269
        series = self.factory.makeProductSeries()
 
270
        bug = self.factory.makeBug(product=series.product)
 
271
        with person_logged_in(series.owner):
 
272
            nomination = bug.addNomination(
 
273
                target=series, owner=series.owner)
 
274
        self.check_heat_queries(nomination)
 
275
 
 
276
    def test_heat_queries_for_distroseries(self):
 
277
        # The number of heat-related queries when approving a distro series
 
278
        # nomination is as low as reasonably possible.
 
279
        series = self.factory.makeDistroSeries()
 
280
        bug = self.factory.makeBug(distribution=series.distribution)
 
281
        with person_logged_in(series.owner):
 
282
            nomination = bug.addNomination(
 
283
                target=series, owner=series.owner)
 
284
        self.check_heat_queries(nomination)