← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/destroy-plus-daily-builds into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/destroy-plus-daily-builds into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #905792 in Launchpad itself: "Timeout on /+daily-builds"
  https://bugs.launchpad.net/launchpad/+bug/905792
  Bug #968998 in Launchpad itself: "RootObject:+daily-builds times out"
  https://bugs.launchpad.net/launchpad/+bug/968998

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/destroy-plus-daily-builds/+merge/123888

Destroy RootObject:+daily-builds. Its main query is horrible with eight joins, takes 5 *minutes* on DF with a cold cache, has been visited for 120 for the past month and has been broken for at least 12 months. It is time for it die, so remove it.
-- 
https://code.launchpad.net/~stevenk/launchpad/destroy-plus-daily-builds/+merge/123888
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/destroy-plus-daily-builds into lp:launchpad.
=== modified file 'lib/lp/code/browser/configure.zcml'
--- lib/lp/code/browser/configure.zcml	2012-08-28 04:16:32 +0000
+++ lib/lp/code/browser/configure.zcml	2012-09-12 06:19:27 +0000
@@ -141,14 +141,6 @@
         name="+index"
         template="../templates/bazaar-index.pt" />
     <browser:page
-        for="lp.services.webapp.interfaces.ILaunchpadRoot"
-        layer="lp.code.publisher.CodeLayer"
-        permission="zope.Public"
-        class="lp.code.browser.recipebuildslisting.CompletedDailyBuildsView"
-        name="+daily-builds"
-        template="../templates/daily-builds-listing.pt" />
-
-    <browser:page
         for="lp.code.interfaces.branchmergeproposal.IBranchMergeProposal"
         layer="lp.code.publisher.CodeLayer"
         name="+hierarchy"

=== removed file 'lib/lp/code/browser/recipebuildslisting.py'
--- lib/lp/code/browser/recipebuildslisting.py	2012-01-01 02:58:52 +0000
+++ lib/lp/code/browser/recipebuildslisting.py	1970-01-01 00:00:00 +0000
@@ -1,91 +0,0 @@
-# Copyright 2010-2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""View for daily builds listings."""
-
-__metaclass__ = type
-
-__all__ = [
-    'CompletedDailyBuildsView',
-    ]
-
-from lazr.enum import (
-    EnumeratedType,
-    Item,
-    )
-from zope.component import getUtility
-from zope.interface import Interface
-from zope.schema import Choice
-
-from lp import _
-from lp.app.browser.launchpadform import (
-    custom_widget,
-    LaunchpadFormView,
-    )
-from lp.app.widgets.itemswidgets import LaunchpadDropdownWidget
-from lp.code.interfaces.recipebuild import IRecipeBuildRecordSet
-from lp.services.webapp.batching import BatchNavigator
-
-
-class RecipeBuildFilter(EnumeratedType):
-    """Choices for how to filter recipe build listings."""
-
-    ALL = Item("""
-        at any time
-
-        Show all most recently completed recipe builds.
-        """)
-
-    WITHIN_30_DAYS = Item("""
-        within last 30 days
-
-        Show only recently completed recipe builds from within the last
-        30 days.
-        """)
-
-
-class RecipeBuildBatchNavigator(BatchNavigator):
-    """A Batch Navigator turn activate table sorting for single page views."""
-
-    @property
-    def table_class(self):
-        if self.has_multiple_pages:
-            return "listing"
-        else:
-            return "listing sortable"
-
-
-class CompletedDailyBuildsView(LaunchpadFormView):
-    """The view to show completed builds for source package recipes."""
-
-    class schema(Interface):
-        when_completed_filter = Choice(
-            title=_('Recipe Build Filter'), vocabulary=RecipeBuildFilter,
-            default=RecipeBuildFilter.ALL,
-            description=_(
-                "Filter for selecting when recipe builds have completed."))
-    field_names = ['when_completed_filter']
-    custom_widget('when_completed_filter', LaunchpadDropdownWidget)
-
-    @property
-    def page_title(self):
-        return 'Packages Built Daily With Recipes'
-
-    def initialize(self):
-        LaunchpadFormView.initialize(self)
-        self.dailybuilds = self.getDailyBuilds()
-        self.batchnav = RecipeBuildBatchNavigator(
-            self.dailybuilds, self.request)
-
-    def getDailyBuilds(self):
-        widget = self.widgets['when_completed_filter']
-        if widget.hasValidInput():
-            when_completed = widget.getInputValue()
-            if when_completed == RecipeBuildFilter.WITHIN_30_DAYS:
-                epoch_days = 30
-            else:
-                epoch_days = None
-        else:
-            epoch_days = None
-        recipe_build_set = getUtility(IRecipeBuildRecordSet)
-        return recipe_build_set.findCompletedDailyBuilds(epoch_days)

=== removed file 'lib/lp/code/browser/tests/test_recipebuildslisting.py'
--- lib/lp/code/browser/tests/test_recipebuildslisting.py	2012-01-01 02:58:52 +0000
+++ lib/lp/code/browser/tests/test_recipebuildslisting.py	1970-01-01 00:00:00 +0000
@@ -1,214 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tests for recipe build listings."""
-
-__metaclass__ = type
-
-
-from zope.component import getUtility
-
-from lp.services.webapp.interfaces import ILaunchpadRoot
-from lp.services.webapp.publisher import canonical_url
-from lp.testing import (
-    ANONYMOUS,
-    BrowserTestCase,
-    login,
-    TestCaseWithFactory,
-    )
-from lp.testing.layers import DatabaseFunctionalLayer
-from lp.testing.matchers import BrowsesWithQueryLimit
-from lp.testing.pages import (
-    extract_text,
-    find_tag_by_id,
-    )
-from lp.testing.views import create_initialized_view
-
-
-class TestRecipeBuildView(TestCaseWithFactory):
-    """Tests for `CompletedDailyBuildsView`."""
-
-    layer = DatabaseFunctionalLayer
-
-    def test_recipebuildrecords(self):
-        all_records, recent_records = (
-            self.factory.makeRecipeBuildRecords(10, 5))
-        login(ANONYMOUS)
-        root = getUtility(ILaunchpadRoot)
-        view = create_initialized_view(root, "+daily-builds", rootsite='code')
-        # It's easier to do it this way than sorted() since __lt__ doesn't
-        # work properly on zope proxies.
-        self.assertEqual(15, view.dailybuilds.count())
-        # By default, all build records will be included in the view.
-        self.assertEqual(set(all_records), set(view.dailybuilds))
-
-
-class TestRecipeBuildListing(BrowserTestCase):
-    """Browser tests for the Recipe Build Listing page."""
-    layer = DatabaseFunctionalLayer
-
-    def _extract_view_text(self, recipe_build_record):
-        text = '\n'.join(str(item) for item in (
-                recipe_build_record.sourcepackagename.name,
-                recipe_build_record.recipe.name,
-                recipe_build_record.recipeowner.displayname,
-                recipe_build_record.archive.displayname,
-                recipe_build_record.most_recent_build_time.strftime(
-                    '%Y-%m-%d %H:%M:%S')))
-        return text
-
-    def _test_recipebuild_listing(self, no_login=False):
-        # Test the text on a recipe build listing page is as expected.
-        all_records, [recent_record] = (
-            self.factory.makeRecipeBuildRecords(1, 5))
-        record_text = self._extract_view_text(recent_record)
-        root = getUtility(ILaunchpadRoot)
-        text = self.getMainText(
-            root, '+daily-builds', rootsite='code', no_login=no_login)
-        expected_text = """
-            Packages Built Daily With Recipes
-            .*
-            Source Package
-            Recipe
-            Recipe Owner
-            Archive
-            Most Recent Build Time
-            """ + record_text
-        self.assertTextMatchesExpressionIgnoreWhitespace(expected_text, text)
-
-    def test_recipebuild_listing_no_records(self):
-        # Test the expected text when there is no data.
-        root = getUtility(ILaunchpadRoot)
-        text = self.getMainText(root, '+daily-builds', rootsite='code')
-        expected_text = "No recently completed daily builds found."
-        self.assertTextMatchesExpressionIgnoreWhitespace(expected_text, text)
-
-    def test_recipebuild_listing_anonymous(self):
-        # Ensure we can see the listing when we are not logged in.
-        self._test_recipebuild_listing(no_login=True)
-
-    def test_recipebuild_listing_with_user(self):
-        # Ensure we can see the listing when we are logged in.
-        self._test_recipebuild_listing()
-
-    def test_recipebuild_listing_querycount(self):
-        # The query count on the recipe build listing page is small enough.
-        # There's a base query count of approx 30, but if the page template
-        # is not set up right, the query count can increases linearly with the
-        # number of records.
-        self.factory.makeRecipeBuildRecords(5, 0)
-        root = getUtility(ILaunchpadRoot)
-        browser_query_limit = BrowsesWithQueryLimit(
-            35, self.user, view_name='+daily-builds', rootsite='code')
-        self.assertThat(root, browser_query_limit)
-
-    def test_recipebuild_url(self):
-        # Check the browser URL is as expected.
-        root_url = self.layer.appserver_root_url(facet='code')
-        user_browser = self.getUserBrowser("%s/+daily-builds" % root_url)
-        self.assertEqual(
-            user_browser.url, "%s/+daily-builds" % root_url)
-
-    def test_recentbuild_filter(self):
-        login(ANONYMOUS)
-        all_records, recent_records = (
-            self.factory.makeRecipeBuildRecords(3, 2))
-        records_text = set()
-        for record in recent_records:
-            record_text = self._extract_view_text(
-                record).replace(' ', '').replace('\n', '')
-            records_text.add(record_text)
-
-        root_url = self.layer.appserver_root_url(facet='code')
-        browser = self.getUserBrowser("%s/+daily-builds" % root_url)
-        status_control = browser.getControl(
-            name='field.when_completed_filter')
-
-        status_control.value = ['WITHIN_30_DAYS']
-        browser.getControl('Filter').click()
-        table = find_tag_by_id(browser.contents, 'daily-build-listing')
-
-        view_records_text = set()
-        for row in table.tbody.fetch('tr'):
-            text = extract_text(row)
-            view_records_text.add(text.replace(' ', '').replace('\n', ''))
-        self.assertEquals(records_text, view_records_text)
-
-    def test_recentbuild_filter_with_no_records(self):
-        # This test ensures that the filter control works properly when the
-        # filtered record set contains no records. We should be able to
-        # select All again and have the page re-display all records."
-
-        login(ANONYMOUS)
-        # Create records all outside the filter time window.
-        all_records, recent_records = (
-            self.factory.makeRecipeBuildRecords(0, 2))
-        records_text = set()
-        for record in all_records:
-            record_text = self._extract_view_text(
-                record).replace(' ', '').replace('\n', '')
-            records_text.add(record_text)
-
-        def check_build_records(table):
-            view_records_text = set()
-            for row in table.tbody.fetch('tr'):
-                text = extract_text(row)
-                view_records_text.add(text.replace(' ', '').replace('\n', ''))
-            self.assertEquals(records_text, view_records_text)
-
-        # Initial rendering has all records.
-        root_url = self.layer.appserver_root_url(facet='code')
-        browser = self.getUserBrowser("%s/+daily-builds" % root_url)
-        table = find_tag_by_id(browser.contents, 'daily-build-listing')
-        check_build_records(table)
-
-        # There are no filtered records.
-        status_control = browser.getControl(
-            name='field.when_completed_filter')
-        status_control.value = ['WITHIN_30_DAYS']
-        browser.getControl('Filter').click()
-        table = find_tag_by_id(browser.contents, 'daily-build-listing')
-        self.assertIs(None, table)
-
-        # We can click All and see the record again.
-        status_control = browser.getControl(
-            name='field.when_completed_filter')
-        status_control.value = ['ALL']
-        browser.getControl('Filter').click()
-        table = find_tag_by_id(browser.contents, 'daily-build-listing')
-        check_build_records(table)
-
-    def test_all_records_filter(self):
-        login(ANONYMOUS)
-        all_records, recent_records = (
-            self.factory.makeRecipeBuildRecords(3, 2))
-        records_text = set()
-        for record in all_records:
-            record_text = self._extract_view_text(
-                record).replace(' ', '').replace('\n', '')
-            records_text.add(record_text)
-
-        root_url = self.layer.appserver_root_url(facet='code')
-        browser = self.getUserBrowser("%s/+daily-builds" % root_url)
-        status_control = browser.getControl(
-            name='field.when_completed_filter')
-
-        status_control.value = ['ALL']
-        browser.getControl('Filter').click()
-        table = find_tag_by_id(browser.contents, 'daily-build-listing')
-
-        view_records_text = set()
-        for row in table.tbody.fetch('tr'):
-            text = extract_text(row)
-            view_records_text.add(text.replace(' ', '').replace('\n', ''))
-        self.assertEquals(records_text, view_records_text)
-
-    def test_one_recipe_redirects_to_recipe_page(self):
-        # Ensure that if the product or person has only one recipe, they are
-        # redirected right to the recipe page.
-        recipe = self.factory.makeSourcePackageRecipe()
-        root_url = self.layer.appserver_root_url(facet='code')
-        recipes_url = '%s/~%s/+recipes' % (root_url, recipe.owner.name)
-        expected_url = canonical_url(recipe)
-        browser = self.getUserBrowser(recipes_url)
-        self.assertEquals(expected_url, browser.url)

=== modified file 'lib/lp/code/stories/branches/xx-bazaar-home.txt'
--- lib/lp/code/stories/branches/xx-bazaar-home.txt	2012-03-01 17:42:28 +0000
+++ lib/lp/code/stories/branches/xx-bazaar-home.txt	2012-09-12 06:19:27 +0000
@@ -152,16 +152,3 @@
     Project
     Last Modified
     Last Commit
-
-
-Recently built recipes
-......................
-
-Source package recipes have their own section on the home page.
-
-    >>> browser.open('http://code.launchpad.dev/')
-    >>> changed = find_tag_by_id(browser.contents, 'build-recipes')
-    >>> print changed.fetch('a')[0]['href']
-    /+daily-builds
-    >>> print changed.fetch('a')[-1]['href']
-    https://help.launchpad.net/Packaging/SourceBuilds

=== modified file 'lib/lp/code/templates/bazaar-index.pt'
--- lib/lp/code/templates/bazaar-index.pt	2012-06-11 00:47:38 +0000
+++ lib/lp/code/templates/bazaar-index.pt	2012-09-12 06:19:27 +0000
@@ -53,8 +53,7 @@
       </p>
       <p id="build-recipes" class="application-summary" style="padding-top: 0.25em;">
         Launchpad can build Ubuntu packages directly from branches using recipes.
-        We currently build over <a href="/+daily-builds">100 different packages</a>
-        into PPAs automatically using this method.
+        We currently build over 100 different packages into PPAs automatically using this method.
         (<a href="https://help.launchpad.net/Packaging/SourceBuilds";>Learn more about recipes</a>)
       </p>
 


Follow ups