Maximiliano Bertacchini has proposed merging 
lp:~maxiberta/launchpad/sitesearch-drop-google-backend into lp:launchpad.

Commit message:
Remove the Google search service backend.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~maxiberta/launchpad/sitesearch-drop-google-backend/+merge/346425

Remove the Google search service backend, leaving all the generic boilerplate 
to make adding a new search engine easier next time.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of 
lp:~maxiberta/launchpad/sitesearch-drop-google-backend into lp:launchpad.
=== modified file 'Makefile'
--- Makefile	2018-04-02 16:40:03 +0000
+++ Makefile	2018-05-21 21:36:59 +0000
@@ -64,7 +64,6 @@
     bin/bingtestservice \
     bin/build-twisted-plugin-cache \
     bin/combine-css \
-    bin/googletestservice \
     bin/harness \
     bin/iharness \
     bin/ipy \

=== modified file 'configs/development/launchpad-lazr.conf'
--- configs/development/launchpad-lazr.conf	2018-03-26 18:59:34 +0000
+++ configs/development/launchpad-lazr.conf	2018-05-21 21:36:59 +0000
@@ -78,14 +78,6 @@
 oops_prefix: X
 error_dir: /var/tmp/lperr
 
-[google]
-# Development and the testrunner should use the stub service by default.
-site: http://launchpad.dev:8092/cse
-client_id: ABCDEF2323
-
-[google_test_service]
-launch: True
-
 [bing]
 # Development and the testrunner should use the stub service by default.
 site: http://launchpad.dev:8093/bingcustomsearch/v7.0/search

=== modified file 'configs/testrunner-appserver/launchpad-lazr.conf'
--- configs/testrunner-appserver/launchpad-lazr.conf	2018-03-16 21:04:45 +0000
+++ configs/testrunner-appserver/launchpad-lazr.conf	2018-05-21 21:36:59 +0000
@@ -11,9 +11,6 @@
 [codeimport]
 macaroon_secret_key: dev-macaroon-secret
 
-[google_test_service]
-launch: False
-
 [bing_test_service]
 launch: False
 

=== modified file 'configs/testrunner/launchpad-lazr.conf'
--- configs/testrunner/launchpad-lazr.conf	2018-03-16 21:04:45 +0000
+++ configs/testrunner/launchpad-lazr.conf	2018-05-21 21:36:59 +0000
@@ -88,9 +88,6 @@
 source_only: True
 root: /tmp/gina_test_archive
 
-[google]
-site: http://launchpad.dev:8092/cse
-
 [bing]
 site: http://launchpad.dev:8093/bingcustomsearch/v7.0/search
 
@@ -108,8 +105,6 @@
 max_attachment_size: 1024
 geoip_database: /usr/share/GeoIP/GeoLiteCity.dat
 logparser_max_parsed_lines: 100000
-# We use the stub Google Service here which maps URL fragment to
-# to static content
 homepage_recent_posts_feed: http://launchpad.dev:8092/blog-feed
 openid_canonical_root: http://testopenid.dev/
 openid_provider_root: http://testopenid.dev/

=== modified file 'lib/lp/app/browser/doc/launchpad-search-pages.txt'
--- lib/lp/app/browser/doc/launchpad-search-pages.txt	2018-04-13 21:57:12 +0000
+++ lib/lp/app/browser/doc/launchpad-search-pages.txt	2018-05-21 21:36:59 +0000
@@ -406,7 +406,7 @@
 Page searches
 -------------
 
-The view uses the GoogleSearchService to locate pages that match the
+The view uses the Search Service to locate pages that match the
 search terms.
 
     >>> search_view = getSearchView(
@@ -418,23 +418,23 @@
     >>> search_view.pages
     <...SiteSearchBatchNavigator ...>
 
-The GoogleSearchService may not be available due to connectivity problems.
+The Search Service may not be available due to connectivity problems.
 The view's has_page_service attribute reports when the search was performed
-with Google page matches.
+with the Search Service page matches.
 
     >>> search_view.has_page_service
     True
 
 The batch navigation heading is created by the view. The heading
 property returns a 2-tuple of singular and plural heading. There
-is a heading when there are only Google page matches...
+is a heading when there are only Search Service page matches...
 
     >>> search_view.has_exact_matches
     False
     >>> search_view.batch_heading
     (u'page matching "bug"', u'pages matching "bug"')
 
-...and a heading for when there are exact matches and Google page
+...and a heading for when there are exact matches and Search Service page
 matches.
 
     >>> search_view = getSearchView(
@@ -518,14 +518,11 @@
     >>> page.summary
     u'...Launchpad\u2019s ...bug... tracker allows collaboration...'
 
-See `google-searchservice.txt` for more information about the
-GoogleSearchService and PageMatch objects.
-
 
 No page matches
 ---------------
 
-When an empty PageMatches object is returned by the GoogleSearchService to
+When an empty PageMatches object is returned by the Search Service to
 the view, there are no matches to show.
 
     >>> search_view = getSearchView(form={'field.text': 'no-meaningful'})
@@ -549,11 +546,11 @@
     True
 
 
-Bad Google response handling
+Bad site search response handling
 ----------------------------
 
 Connectivity problems can cause missing or incomplete responses from
-Google. The LaunchpadSearchView will display the other searches and
+the site search engine. The LaunchpadSearchView will display the other searches and
 show a message explaining that the user can search again to find
 matching pages.
 
@@ -631,7 +628,7 @@
 The LaunchpadSearchView uses two helper classes to work with
 PageMatches.
 
-The PageMatches object returned by the GoogleSearchService contains 20
+The PageMatches object returned by the Search Service contains 20
 or fewer PageMatches of what could be thousands of matches. Google
 requires client's to make repeats request to step though the batches of
 matches. The Windowed list is a list that contains only a subset of its
@@ -661,7 +658,7 @@
 
 The SiteSearchBatchNavigator restricts the batch size to 20. the 'batch'
 parameter that comes from the URL is ignored. For example, setting
-the 'batch' parameter to 100 has no affect upon the Google search
+the 'batch' parameter to 100 has no affect upon the site search
 or on the navigator object.
 
     >>> from lp.app.browser.root import SiteSearchBatchNavigator
@@ -699,7 +696,7 @@
     '...start=20'
 
 The PageMatches object can be smaller than 20, for instance, pages
-without titles are skipped when parsing the Google Search XML. The size
+without titles are skipped when parsing the search engine response. The size
 of the batch is still 20, but when the items in the batch are iterated,
 the true size can be seen. For example there could be only 3 matches in
 the PageMatches object, so only 3 are yielded. The start of the next

=== modified file 'lib/lp/app/browser/tests/test_views.py'
--- lib/lp/app/browser/tests/test_views.py	2018-04-13 21:57:12 +0000
+++ lib/lp/app/browser/tests/test_views.py	2018-05-21 21:36:59 +0000
@@ -14,7 +14,6 @@
 from lp.services.testing import build_test_suite
 from lp.testing.layers import (
     BingLaunchpadFunctionalLayer,
-    GoogleLaunchpadFunctionalLayer,
     PageTestLayer,
     )
 from lp.testing.systemdocs import (
@@ -26,7 +25,6 @@
 
 here = os.path.dirname(os.path.realpath(__file__))
 bing_flag = FeatureFixture({'sitesearch.engine.name': 'bing'})
-google_flag = FeatureFixture({'sitesearch.engine.name': 'google'})
 
 
 def setUp_bing(test):
@@ -34,21 +32,11 @@
     bing_flag.setUp()
 
 
-def setUp_google(test):
-    setUp(test)
-    google_flag.setUp()
-
-
 def tearDown_bing(test):
     bing_flag.cleanUp()
     tearDown(test)
 
 
-def tearDown_google(test):
-    google_flag.cleanUp()
-    tearDown(test)
-
-
 # The default layer of view tests is the DatabaseFunctionalLayer. Tests
 # that require something special like the librarian or mailman must run
 # on a layer that sets those services up.
@@ -59,12 +47,6 @@
         setUp=setUp_bing, tearDown=tearDown_bing,
         layer=BingLaunchpadFunctionalLayer,
         stdout_logging_level=logging.WARNING),
-    'launchpad-search-pages.txt(Google)': LayeredDocFileSuite(
-        '../doc/launchpad-search-pages.txt',
-        id_extensions=['launchpad-search-pages.txt(Google)'],
-        setUp=setUp_google, tearDown=tearDown_google,
-        layer=GoogleLaunchpadFunctionalLayer,
-        stdout_logging_level=logging.WARNING),
     # Run these doctests again with the default search engine.
     'launchpad-search-pages.txt': LayeredDocFileSuite(
         '../doc/launchpad-search-pages.txt',

=== modified file 'lib/lp/app/tests/test_doc.py'
--- lib/lp/app/tests/test_doc.py	2018-04-13 20:47:03 +0000
+++ lib/lp/app/tests/test_doc.py	2018-05-21 21:36:59 +0000
@@ -23,7 +23,6 @@
 
 here = os.path.dirname(os.path.realpath(__file__))
 bing_flag = FeatureFixture({'sitesearch.engine.name': 'bing'})
-google_flag = FeatureFixture({'sitesearch.engine.name': 'google'})
 
 
 def setUp_bing(test):
@@ -31,21 +30,11 @@
     bing_flag.setUp()
 
 
-def setUp_google(test):
-    setUpGlobs(test)
-    google_flag.setUp()
-
-
 def tearDown_bing(test):
     bing_flag.cleanUp()
     tearDown(test)
 
 
-def tearDown_google(test):
-    google_flag.cleanUp()
-    tearDown(test)
-
-
 special = {
     'tales.txt': LayeredDocFileSuite(
         '../doc/tales.txt',
@@ -60,11 +49,6 @@
         id_extensions=['site-search.txt(Bing)'],
         setUp=setUp_bing, tearDown=tearDown_bing,
         ),
-    'stories/launchpad-search(Google)': PageTestSuite(
-        '../stories/launchpad-search/',
-        id_extensions=['site-search.txt(Google)'],
-        setUp=setUp_google, tearDown=tearDown_google,
-        ),
     # Run these doctests again with the default search engine.
     '../stories/launchpad-search': PageTestSuite(
         '../stories/launchpad-search/',

=== modified file 'lib/lp/scripts/runlaunchpad.py'
--- lib/lp/scripts/runlaunchpad.py	2018-03-16 21:04:45 +0000
+++ lib/lp/scripts/runlaunchpad.py	2018-05-21 21:36:59 +0000
@@ -26,10 +26,7 @@
     pidfile_path,
     )
 from lp.services.rabbit.server import RabbitServer
-from lp.services.sitesearch import (
-    bingtestservice,
-    googletestservice,
-    )
+from lp.services.sitesearch import bingtestservice
 from lp.services.txlongpoll.server import TxLongPollServer
 
 
@@ -146,16 +143,6 @@
         process.stdin.close()
 
 
-class GoogleWebService(Service):
-
-    @property
-    def should_launch(self):
-        return config.google_test_service.launch
-
-    def launch(self):
-        self.addCleanup(stop_process, googletestservice.start_as_process())
-
-
 class BingWebService(Service):
 
     @property
@@ -295,7 +282,6 @@
     'mailman': MailmanService(),
     'bing-webservice': BingWebService(),
     'codebrowse': CodebrowseService(),
-    'google-webservice': GoogleWebService(),
     'memcached': MemcachedService(),
     'rabbitmq': RabbitService(),
     'txlongpoll': TxLongPollService(),

=== modified file 'lib/lp/scripts/tests/test_runlaunchpad.py'
--- lib/lp/scripts/tests/test_runlaunchpad.py	2018-03-29 14:41:36 +0000
+++ lib/lp/scripts/tests/test_runlaunchpad.py	2018-05-21 21:36:59 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for runlaunchpad.py"""
@@ -151,8 +151,6 @@
         # run.
         if config.bing_test_service.launch:
             expected.append(SERVICES['bing-webservice'])
-        if config.google_test_service.launch:
-            expected.append(SERVICES['google-webservice'])
 
         # RabbitMQ may or may not be asked to run.
         if config.rabbitmq.launch:

=== modified file 'lib/lp/services/config/schema-lazr.conf'
--- lib/lp/services/config/schema-lazr.conf	2018-04-12 19:59:21 +0000
+++ lib/lp/services/config/schema-lazr.conf	2018-05-21 21:36:59 +0000
@@ -763,31 +763,6 @@
 distroseries: experimental
 pocketrelease: experimental
 
-[google_test_service]
-# Run a web service stub that simulates the Google search service.
-
-# Where are our canned XML responses stored?
-canned_response_directory: lib/lp/services/sitesearch/tests/data/
-
-# Which file maps service URLs to the XML that the server returns?
-mapfile: lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt
-
-# Where should the service log files live?
-log: logs/google-stub.log
-
-# Do we actually want to run the service?
-launch: False
-
-[google]
-# client_id is the unique id Launchpad was issued by Google.
-# datatype: string
-client_id:
-
-# site is the host and path that search requests are made to.
-# eg. http://www.google.com/cse
-# datatype: string, a url to a host
-site: http://www.google.com/cse
-
 [sitesearch]
 # url_rewrite_exceptions is a list of launchpad.net domains that must
 # not be rewritten.

=== modified file 'lib/lp/services/features/flags.py'
--- lib/lp/services/features/flags.py	2018-03-30 23:06:00 +0000
+++ lib/lp/services/features/flags.py	2018-05-21 21:36:59 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __all__ = [
@@ -236,7 +236,7 @@
      ''),
     ('sitesearch.engine.name',
      'space delimited',
-     'Name of the site search engine backend ("google" or "bing").',
+     'Name of the site search engine backend (only "bing" is available).',
      'bing',
      'Site search engine',
      ''),

=== modified file 'lib/lp/services/sitesearch/__init__.py'
--- lib/lp/services/sitesearch/__init__.py	2018-04-12 19:59:21 +0000
+++ lib/lp/services/sitesearch/__init__.py	2018-05-21 21:36:59 +0000
@@ -7,7 +7,6 @@
 
 __all__ = [
     'BingSearchService',
-    'GoogleSearchService',
     'PageMatch',
     'PageMatches',
     ]
@@ -18,7 +17,6 @@
     parse_qsl,
     urlunparse,
     )
-import xml.etree.cElementTree as ET
 
 from lazr.restful.utils import get_current_browser_request
 from lazr.uri import URI
@@ -27,7 +25,6 @@
 
 from lp.services.config import config
 from lp.services.sitesearch.interfaces import (
-    GoogleWrongGSPVersion,
     ISearchResult,
     ISearchResults,
     ISearchService,
@@ -163,182 +160,6 @@
 
 
 @implementer(ISearchService)
-class GoogleSearchService:
-    """See `ISearchService`.
-
-    A search service that searches Google for launchpad.net pages.
-    """
-
-    _default_values = {
-        'client': 'google-csbe',
-        'cx': None,
-        'ie': 'utf8',
-        'num': 20,
-        'oe': 'utf8',
-        'output': 'xml_no_dtd',
-        'start': 0,
-        'q': None,
-        }
-
-    @property
-    def client_id(self):
-        """The client-id issued by Google.
-
-        Google requires that each client of the Google Search Engine
-        service to pass its id as a parameter in the request URL.
-        """
-        return config.google.client_id
-
-    @property
-    def site(self):
-        """The URL to the Google Search Engine service.
-
-        The URL is probably http://www.google.com/search.
-        """
-        return config.google.site
-
-    def search(self, terms, start=0):
-        """See `ISearchService`.
-
-        The config.google.client_id is used as Google client-id in the
-        search request. Search returns 20 or fewer results for each query.
-        For terms that match more than 20 results, the start param can be
-        used over multiple queries to get successive sets of results.
-
-        :return: `ISearchResults` (PageMatches).
-        :raise: `GoogleWrongGSPVersion` if the xml cannot be parsed.
-        """
-        search_url = self.create_search_url(terms, start=start)
-        request = get_current_browser_request()
-        timeline = get_request_timeline(request)
-        action = timeline.start("google-search-api", search_url)
-        try:
-            response = urlfetch(search_url)
-        except (TimeoutError, requests.RequestException) as error:
-            # Google search service errors are not code errors. Let the
-            # call site choose to handle the unavailable service.
-            raise SiteSearchResponseError(
-                "The response errored: %s" % str(error))
-        finally:
-            action.finish()
-        page_matches = self._parse_search_response(response.content)
-        return page_matches
-
-    def _checkParameter(self, name, value, is_int=False):
-        """Check that a parameter value is not None or an empty string."""
-        if value in (None, ''):
-            raise ValueError("Missing value for parameter '%s'." % name)
-        if is_int:
-            try:
-                int(value)
-            except ValueError:
-                raise ValueError(
-                    "Value for parameter '%s' is not an int." % name)
-
-    def create_search_url(self, terms, start=0):
-        """Return a Google search url."""
-        self._checkParameter('q', terms)
-        self._checkParameter('start', start, is_int=True)
-        self._checkParameter('cx', self.client_id)
-        search_params = dict(self._default_values)
-        search_params['q'] = terms.encode('utf8')
-        search_params['start'] = start
-        search_params['cx'] = self.client_id
-        query_string = urllib.urlencode(sorted(search_params.items()))
-        return self.site + '?' + query_string
-
-    def _getElementsByAttributeValue(self, doc, path, name, value):
-        """Return a list of elements whose named attribute matches the value.
-
-        The cElementTree implementation does not support attribute selection
-        (@) or conditional expressions (./PARAM[@name = 'start']).
-
-        :param doc: An ElementTree of an XML document.
-        :param path: A string path to match the first element.
-        :param name: The attribute name to check.
-        :param value: The string value of the named attribute.
-        """
-        elements = doc.findall(path)
-        return [element for element in elements
-                if element.get(name) == value]
-
-    def _getElementByAttributeValue(self, doc, path, name, value):
-        """Return the first element whose named attribute matches the value.
-
-        :param doc: An ElementTree of an XML document.
-        :param path: A string path to match an element.
-        :param name: The attribute name to check.
-        :param value: The string value of the named attribute.
-        """
-        return self._getElementsByAttributeValue(doc, path, name, value)[0]
-
-    def _parse_search_response(self, gsp_xml):
-        """Return a `PageMatches` object.
-
-        :param gsp_xml: A string that should be Google Search Protocol
-            version 3.2 XML. There is no guarantee that other GSP versions
-            can be parsed.
-        :return: `ISearchResults` (PageMatches).
-        :raise: `SiteSearchResponseError` if the xml is incomplete.
-        :raise: `GoogleWrongGSPVersion` if the xml cannot be parsed.
-        """
-        try:
-            gsp_doc = ET.fromstring(gsp_xml)
-            start_param = self._getElementByAttributeValue(
-                gsp_doc, './PARAM', 'name', 'start')
-        except (SyntaxError, IndexError):
-            raise SiteSearchResponseError(
-                "The response was incomplete, no xml.")
-        try:
-            start = int(start_param.get('value'))
-        except (AttributeError, ValueError):
-            # The datatype is not what PageMatches requires.
-            raise GoogleWrongGSPVersion(
-                "Could not get the 'start' from the GSP XML response.")
-        page_matches = []
-        total = 0
-        results = gsp_doc.find('RES')
-        if results is None:
-            # Google did not match any pages. Return an empty PageMatches.
-            return PageMatches(page_matches, start, total)
-
-        try:
-            total = int(results.find('M').text)
-        except (AttributeError, ValueError):
-            # The datatype is not what PageMatches requires.
-            raise GoogleWrongGSPVersion(
-                "Could not get the 'total' from the GSP XML response.")
-        if total < 0:
-            # See bug 683115.
-            total = 0
-        for result in results.findall('R'):
-            url_tag = result.find('U')
-            title_tag = result.find('T')
-            summary_tag = result.find('S')
-            if None in (url_tag, title_tag, summary_tag):
-                # Google indexed a bad page, or the page may be marked for
-                # removal from the index. We should not include this.
-                continue
-            title = title_tag.text
-            url = url_tag.text
-            summary = summary_tag.text
-            if None in (url, title, summary):
-                # There is not enough data to create a PageMatch object.
-                # This can be caused by an empty title or summary which
-                # has been observed for pages that are from vhosts that
-                # should not be indexed.
-                continue
-            summary = summary.replace('<br>', '')
-            page_matches.append(PageMatch(title, url, summary))
-        if len(page_matches) == 0 and total > 20:
-            # No viable page matches could be found in the set and there
-            # are more possible matches; the XML may be the wrong version.
-            raise GoogleWrongGSPVersion(
-                "Could not get any PageMatches from the GSP XML response.")
-        return PageMatches(page_matches, start, total)
-
-
-@implementer(ISearchService)
 class BingSearchService:
     """See `ISearchService`.
 

=== modified file 'lib/lp/services/sitesearch/configure.zcml'
--- lib/lp/services/sitesearch/configure.zcml	2018-03-27 20:41:35 +0000
+++ lib/lp/services/sitesearch/configure.zcml	2018-05-21 21:36:59 +0000
@@ -16,13 +16,6 @@
   </class>
 
   <securedutility
-    name="google"
-    class="lp.services.sitesearch.GoogleSearchService"
-    provides="lp.services.sitesearch.interfaces.ISearchService">
-    <allow interface="lp.services.sitesearch.interfaces.ISearchService" />
-  </securedutility>
-
-  <securedutility
     name="bing"
     class="lp.services.sitesearch.BingSearchService"
     provides="lp.services.sitesearch.interfaces.ISearchService">

=== removed file 'lib/lp/services/sitesearch/googletestservice.py'
--- lib/lp/services/sitesearch/googletestservice.py	2018-04-12 20:04:28 +0000
+++ lib/lp/services/sitesearch/googletestservice.py	1970-01-01 00:00:00 +0000
@@ -1,82 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2018 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""
-This script runs a simple HTTP server. The server returns XML files
-when given certain user-configurable URLs.
-"""
-from __future__ import absolute_import, print_function, unicode_literals
-
-__metaclass__ = type
-
-import logging
-import os
-
-from six.moves.BaseHTTPServer import HTTPServer
-
-from lp.services.config import config
-from lp.services.osutils import ensure_directory_exists
-from lp.services.pidfile import make_pidfile
-from lp.services.sitesearch import testservice
-
-
-# Set up basic logging.
-log = logging.getLogger(__name__)
-
-# The default service name, used by the Launchpad service framework.
-service_name = 'google-webservice'
-
-
-class GoogleRequestHandler(testservice.RequestHandler):
-    default_content_type = 'text/xml; charset=UTF-8'
-    log = log
-    mapfile = config.google_test_service.mapfile
-    content_dir = config.google_test_service.canned_response_directory
-
-
-def start_as_process():
-    return testservice.start_as_process('googletestservice')
-
-
-def get_service_endpoint():
-    """Return the host and port that the service is running on."""
-    return testservice.hostpair(config.google.site)
-
-
-def service_is_available():
-    host, port = get_service_endpoint()
-    return testservice.service_is_available(host, port)
-
-
-def wait_for_service():
-    host, port = get_service_endpoint()
-    return testservice.wait_for_service(host, port)
-
-
-def kill_running_process():
-    global service_name
-    host, port = get_service_endpoint()
-    return testservice.kill_running_process(service_name, host, port)
-
-
-def main():
-    """Run the HTTP server."""
-    # Redirect our service output to a log file.
-    global log
-    ensure_directory_exists(os.path.dirname(config.google_test_service.log))
-    filelog = logging.FileHandler(config.google_test_service.log)
-    log.addHandler(filelog)
-    log.setLevel(logging.DEBUG)
-
-    # To support service shutdown we need to create a PID file that is
-    # understood by the Launchpad services framework.
-    global service_name
-    make_pidfile(service_name)
-
-    host, port = get_service_endpoint()
-    server = HTTPServer((host, port), GoogleRequestHandler)
-
-    log.info("Starting HTTP Google webservice server on port %s", port)
-    server.serve_forever()

=== modified file 'lib/lp/services/sitesearch/interfaces.py'
--- lib/lp/services/sitesearch/interfaces.py	2018-04-03 05:44:57 +0000
+++ lib/lp/services/sitesearch/interfaces.py	2018-05-21 21:36:59 +0000
@@ -9,7 +9,6 @@
     'ISearchResult',
     'ISearchResults',
     'ISearchService',
-    'GoogleWrongGSPVersion',
     'SiteSearchResponseError',
     'active_search_service',
     ]
@@ -80,10 +79,6 @@
         """Iterate over the items in the collection."""
 
 
-class GoogleWrongGSPVersion(ValueError):
-    """Raised when the content is not parsable Google Search Protocol XML."""
-
-
 class SiteSearchResponseError(ValueError):
     """Raised when the search engine's response cannot be parsed."""
 

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml	2009-08-13 15:12:16 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml	1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context><RES SN="1" EN="20">
-
-<M>25</M>
-<FI/><NB><NU>/custom?q=bugs+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=0&amp;sa=N</NU>
-</NB>
-
-<R N="1"><U>https://bugs.launchpad.net/</U><UE>https://bugs.launchpad.net/</UE><T>Launchpad Bugs</T><RK>0</RK><CRAWLDATE>17 hours ago</CRAWLDATE><S>&lt;b&gt;Bug&lt;/b&gt; tracking &lt;b&gt;...&lt;/b&gt; Search &lt;b&gt;bugs&lt;/b&gt; reports &lt;b&gt;...&lt;/b&gt; Launchpad’s &lt;b&gt;bug&lt;/b&gt; &lt;br&gt; tracker allows collaboration</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><RT/></HAS></R>
-
-<R N="2"><U>https://bugs.launchpad.net/ubuntu</U><UE>https://bugs.launchpad.net/ubuntu</UE><T>Bugs in Ubuntu Linux</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo &lt;br&gt; porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="37k" CID="5y3q5Izgz60J"/><RT/></HAS></R>
-
-<R N="3"><U>https://bugs.launchpad.net/~name12</U><UE>https://bugs.launchpad.net/~name12</UE><T>Bugs related to Sample Person</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><RT/></HAS></R>
-
-<R N="4"><U>https://bugs.launchpad.net/bugs/1</U><UE>https://bugs.launchpad.net/bugs/1</UE><T>&lt;b&gt;Bug&lt;/b&gt; #1 in Mozilla Firefox: “Firefox does not support SVG”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="58k" CID="TnoSh7JenqwJ"/><RT/></HAS></R>
-
-<R N="5"><U>https://bugs.launchpad.net/ubuntu/+source/thunderbird/?field.tag=crash</U><UE>https://bugs.launchpad.net/ubuntu/+source/thunderbird/?field.tag=crash</UE><T>Bugs in Source Package "thunderbird" in Ubuntu Linux</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="64k" CID="vqkMzdYmI84J"/><RT/></HAS></R>
-
-<R N="6"><U>https://bugs.launchpad.net/ubuntu/+source/thunderbird/+bug/9</U><UE>https://bugs.launchpad.net/ubuntu/+source/thunderbird/+bug/9</UE><T>&lt;b&gt;Bug&lt;/b&gt; #9 in thunderbird (Ubuntu): “Thunderbird crashes”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="36k" CID="Dwzmpo41A5gJ"/><RT/></HAS></R>
-
-<R N="7"><U>https://bugs.launchpad.net/jokosher/+bug/11</U><UE>https://bugs.launchpad.net/jokosher/+bug/11</UE><T>&lt;b&gt;Bug&lt;/b&gt; #11 in Jokosher: “Make Jokosher use autoaudiosink”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="41k" CID="CEH7HMkU_cAJ"/><RT/></HAS></R>
-
-<R N="8"><U>https://bugs.launchpad.net/evolution/+bug/7</U><UE>https://bugs.launchpad.net/evolution/+bug/7</UE><T>&lt;b&gt;Bug&lt;/b&gt; #7 in Evolution: “A test bug”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="40k" CID="Q5nqL6XVMqwJ"/><RT/></HAS></R>
-
-<R N="9"><U>https://bugs.launchpad.net/ubuntu/+bug/2</U><UE>https://bugs.launchpad.net/ubuntu/+bug/2</UE><T>&lt;b&gt;Bug&lt;/b&gt; #2 in Ubuntu: “Blackhole Trash folder”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="37k" CID="T5hMsN5SD4UJ"/><RT/></HAS></R>
-
-<R N="10"><U>https://bugs.launchpad.net/debian/+source/mozilla-firefox/+bug/1</U><UE>https://bugs.launchpad.net/debian/+source/mozilla-firefox/+bug/1</UE><T>&lt;b&gt;Bug&lt;/b&gt; #1 in mozilla-firefox (Debian): “Firefox does not support SVG”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="38k" CID="8btScQoYx0oJ"/><RT/></HAS></R>
-
-<R N="11"><U>https://bugs.launchpad.net/tomcat/+bug/2</U><UE>https://bugs.launchpad.net/tomcat/+bug/2</UE><T>&lt;b&gt;Bug&lt;/b&gt; #2 in Tomcat: “Blackhole Trash folder”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="38k" CID="Q_XFrcs8bcIJ"/><RT/></HAS></R>
-
-<R N="12"><U>https://bugs.launchpad.net/firefox/1.0/+bug/5</U><UE>https://bugs.launchpad.net/firefox/1.0/+bug/5</UE><T>&lt;b&gt;Bug&lt;/b&gt; #5 in Mozilla Firefox 1.0: “Firefox install instructions should be complete”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="29k" CID="fTmhUHBzOv4J"/><RT/></HAS></R>
-
-<R N="13"><U>https://code.launchpad.net/~marysimpson/firefox/release-0.9.2</U><UE>https://code.launchpad.net/~marysimpson/firefox/release-0.9.2</UE><T>“Mozilla Firefox 0.9.2” branch in Launchpad</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><RT/></HAS></R>
-
-<R N="14"><U>https://bugs.launchpad.net/thunderbird/+bug/15</U><UE>https://bugs.launchpad.net/thunderbird/+bug/15</UE><T>&lt;b&gt;Bug&lt;/b&gt; #15 in Mozilla Thunderbird: “Nonsensical bugs are useless”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="36k" CID="DTyllBtRgKwJ"/><RT/></HAS></R>
-
-<R N="15"><U>https://bugs.launchpad.net/bugs/12</U><UE>https://bugs.launchpad.net/bugs/12</UE><T>&lt;b&gt;Bug&lt;/b&gt; #12 in Jokosher: “Copy, Cut and Delete operations should work on selections”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="34k" CID="1kGRGgf2FtkJ"/><RT/></HAS></R>
-
-<R N="16"><U>https://bugs.launchpad.net/jokosher/+bug/12</U><UE>https://bugs.launchpad.net/jokosher/+bug/12</UE><T>&lt;b&gt;Bug&lt;/b&gt; #12 in Jokosher: “Copy, Cut and Delete operations should work on selections”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="57k" CID="KmwXX8kaa8MJ"/><RT/></HAS></R>
-
-<R N="17"><U>https://bugs.launchpad.net/debian/sarge/+source/mozilla-firefox/+bug/3</U><UE>https://bugs.launchpad.net/debian/sarge/+source/mozilla-firefox/+bug/3</UE><T>&lt;b&gt;Bug&lt;/b&gt; #3 in mozilla-firefox (Debian Sarge): “Bug Title Test”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="37k" CID="bpOa7nDcPf4J"/><RT/></HAS></R>
-
-<R N="18"><U>https://bugs.launchpad.net/firefox/+bug/4</U><UE>https://bugs.launchpad.net/firefox/+bug/4</UE><T>&lt;b&gt;Bug&lt;/b&gt; #4 in Mozilla Firefox: “Reflow problems with complex page layouts”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="43k" CID="jUa1q7DI9y0J"/><RT/></HAS></R>
-
-<R N="19"><U>https://bugs.launchpad.net/firefox/</U><UE>https://bugs.launchpad.net/firefox/</UE><T>Bugs in Mozilla Firefox</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="44k" CID="cHqxYeD9FV4J"/><RT/></HAS></R>
-
-<R N="20"><U>https://bugs.launchpad.net/bugs/9</U><UE>https://bugs.launchpad.net/bugs/9</UE><T>&lt;b&gt;Bug&lt;/b&gt; #9 in thunderbird (Ubuntu): “Thunderbird crashes”</T><RK>0</RK><CRAWLDATE>18 hours ago</CRAWLDATE><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="28k" CID="zb4EoD-fVC0J"/><RT/></HAS></R>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml	2008-05-23 20:06:17 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml	1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="20" original_value="20"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context><RES SN="21" EN="25">
-
-<M>25</M>
-<FI/><NB><NU>/custom?q=bugs+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=20&amp;sa=N</NU>
-</NB>
-
-<R N="1"><U>https://bugs.launchpad.net/ubuntu/hoary/+bug/2</U><UE>https://bugs.launchpad.net/ubuntu/hoary/+bug/2</UE><T>&lt;b&gt;Bug&lt;/b&gt; #2 in Ubuntu Hoary: “Blackhole Trash folder”</T><RK>0</RK><CRAWLDATE>17 hours ago</CRAWLDATE><S>&lt;b&gt;Bug&lt;/b&gt; tracking &lt;b&gt;...&lt;/b&gt; Search &lt;b&gt;bugs&lt;/b&gt; reports &lt;b&gt;...&lt;/b&gt; Launchpad’s &lt;b&gt;bug&lt;/b&gt; tracker allows collaboration</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><RT/></HAS></R>
-
-<R N="2"><U>https://bugs.launchpad.net/debian/+source/mozilla-firefox/+bug/2</U><UE>https://bugs.launchpad.net/debian/+source/mozilla-firefox/+bug/2</UE><T>&lt;b&gt;Bug&lt;/b&gt; #2 in mozilla-firefox (Debian): “Blackhole Trash folder”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="37k" CID="5y3q5Izgz60J"/><RT/></HAS></R>
-
-<R N="3"><U>https://bugs.launchpad.net/debian/+source/mozilla-firefox/+bug/3</U><UE>https://bugs.launchpad.net/debian/+source/mozilla-firefox/+bug/3</UE><T>&lt;b&gt;Bug&lt;/b&gt; #3 in mozilla-firefox (Debian): “Bug Title Test”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><RT/></HAS></R>
-
-<R N="4"><U>https://bugs.launchpad.net/bugs/bugtrackers</U><UE>https://bugs.launchpad.net/bugs/bugtrackers</UE><T>&lt;b&gt;Bug&lt;/b&gt; trackers registered in Launchpad</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="58k" CID="TnoSh7JenqwJ"/><RT/></HAS></R>
-
-<R N="5"><U>https://bugs.launchpad.net/bugs/bugtrackers/debbugs</U><UE>https://bugs.launchpad.net/bugs/bugtrackers/debbugs</UE><T>&lt;b&gt;Bug&lt;/b&gt; tracker “Debian Bug tracker”</T><RK>0</RK><S>Lorem ipsum dolor &lt;b&gt;bug&lt;/b&gt; amet, consectetuer adipiscing elit &lt;b&gt;...&lt;/b&gt; Proin &lt;b&gt;bug&lt;/b&gt; sem at porta suscipit, arcu justo porttitor odio &lt;b&gt;...&lt;/b&gt; ut &lt;b&gt;bug&lt;/b&gt; sem odio scelerisque metus.</S><LANG>en</LANG><Label>_cse_ixpjdn21yfg</Label><HAS><L/><C SZ="64k" CID="vqkMzdYmI84J"/><RT/></HAS></R>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml	2008-05-15 21:58:33 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml	1970-01-01 00:00:00 +0000
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context>
-
-<RES SN="1" EN="1">
-<M>~1</M>
-<FI/><NB><NU>/custom?q=bugs+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=0&amp;sa=N</NU>
-</NB>
-
-<R N="1">
-  <U>https://bugs.launchpad.net/</U>
-  <UE>https://bugs.launchpad.net/</UE>
-  <T>Launchpad Bugs</T>
-  <RK>0</RK>
-  <CRAWLDATE>17 hours ago</CRAWLDATE>
-  <S>This 'R'esult is fine, but the 'M' element above is not an int.</S>
-  <LANG>en</LANG>
-  <Label>_cse_ixpjdn21yfg</Label>
-  <HAS><L/><RT/></HAS>
-</R>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml	2008-05-15 21:58:33 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml	1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context>
-
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml	2008-12-05 19:41:05 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml	1970-01-01 00:00:00 +0000
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.3">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context>
-
-<RES SN="1" EN="1">
-<M>1000</M>
-<FI/><NB><NU>/custom?q=bugs+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=0&amp;sa=N</NU>
-</NB>
-
-<RESULT N="1">
-  <url>https://bugs.launchpad.net/</url>
-  <UE>https://bugs.launchpad.net/</UE>
-  <T>Launchpad Bugs</T>
-  <RK>0</RK>
-  <CRAWLDATE>17 hours ago</CRAWLDATE>
-  <S>This 'R'esult is missing a 'U' element, it has a 'url' instead.</S>
-  <LANG>en</LANG>
-  <Label>_cse_ixpjdn21yfg</Label>
-  <HAS><L/><RT/></HAS>
-</RESULT>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml	2008-12-05 16:02:02 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml	1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt	2018-03-16 14:02:16 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-# This file defines a mapping of Google search service URLs to the XML
-# files that should be returned by them.
-#
-# The format is 'url XMLfile'. Blank lines and lines starting with '#'
-# are ignored.
-#
-# The special URL, '*', is returned for all un-mapped URLs.
-
-* googlesearchservice-no-results.xml
-
-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=bug&start=0 googlesearchservice-bugs-1.xml
-
-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=bug&start=20 googlesearchservice-bugs-2.xml
-
-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=launchpad&start=0 googlesearchservice-bugs-1.xml
-
-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=launchpad&start=20 googlesearchservice-bugs-2.xml
-
-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=gnomebaker&start=0 googlesearchservice-incomplete-response.xml
-
-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=no-meaningful&start=0 googlesearchservice-no-meaningful-results.xml
-
-# This stub service is also used to impersonate the Blog feed
-/blog-feed blog.launchpad.net-feed.xml

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml	2008-05-29 21:40:39 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml	1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.574436</TM>
-<Q>edge site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="edge" original_value="gobuntu"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI" original_value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context>
-<title>Launchpad Search Engine</title>
-</Context>
-<RES SN="1" EN="2">
-
-<M>2</M>
-<FI/>
-<NB>
-<NU>/custom?q=gobuntu+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=20&amp;sa=N</NU>
-</NB>
-
-<R N="1">
-<U>https://blueprints.edge.launchpad.net/ubuntu/+spec/gobuntu-hardy</U>
-<UE>https://blueprints.edge.launchpad.net/ubuntu/%2Bspec/gobuntu-hardy</UE>
-<T>Blueprint: &lt;b&gt;gobuntu&lt;/b&gt; hardy</T>
-<RK>0</RK>
-<S></S>
-<LANG>en</LANG>
-<Label>_cse_ixpjdn21yfg</Label>
-<HAS>
-<L/>
-<RT/>
-</HAS>
-</R>
-
-<R N="2">
-<U>https://blueprints.launchpad.net/ubuntu/+spec/gobuntu-hardy</U>
-<UE>https://blueprints.launchpad.net/ubuntu/%2Bspec/gobuntu-hardy</UE>
-<T>Blueprint: &lt;b&gt;Gobuntu&lt;/b&gt; 8.04</T>
-<RK>0</RK>
-<S>Discuss what needs to be done for &lt;b&gt;Gobuntu&lt;/b&gt; and what can be achieved in the Hardy &lt;br&gt;  time frame. Read the full specification » &lt;b&gt;...&lt;/b&gt;</S>
-<LANG>en</LANG>
-<Label>_cse_ixpjdn21yfg</Label>
-<HAS>
-<L/>
-<C SZ="17k" CID="3PPx0kdgdSsJ"/>
-<RT/>
-</HAS>
-</R>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml	2010-10-24 21:00:11 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml	1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.574436</TM>
-<Q>edge site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="edge" original_value="edge"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI" original_value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context>
-<title>Launchpad Search Engine</title>
-</Context>
-<RES SN="1" EN="2">
-
-<M>2</M>
-<FI/>
-<NB>
-<NU>/custom?q=edge+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=20&amp;sa=N</NU>
-</NB>
-
-<R N="1">
-<U>https://launchpad.net/gc</U>
-<UE>https://launchpad.net/gc</UE>
-<RK>0</RK>
-<S>
-</S>
-<LANG>en</LANG>
-<Label>_cse_ixpjdn21yfg</Label>
-<HAS>
-<L/>
-<RT/>
-</HAS>
-</R>
-
-<R N="2">
-<U>https://bugs.launchpad.net/bugs/205991</U>
-<UE>https://bugs.launchpad.net/bugs/205991</UE>
-<T>Bug #205991 in Ubuntu: “Can&amp;#39;t pair Bluetooth Logitech DiNovo &lt;b&gt;Edge&lt;/b&gt; &lt;b&gt;...&lt;/b&gt;</T>
-<RK>0</RK>
-<S>Problem: I am trying to connect my Bluetooth Logitech DiNovo &lt;b&gt;Edge&lt;/b&gt; keyboard to &lt;br&gt;  Ubuntu 8.04. I put the keyboard in discovery mode and it shows up in the &lt;b&gt;...&lt;/b&gt;</S>
-<LANG>en</LANG>
-<Label>_cse_ixpjdn21yfg</Label>
-<HAS>
-<L/>
-<C SZ="28k" CID="iuKmxfKzs1UJ"/>
-<RT/>
-</HAS>
-</R>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml	2008-05-29 21:40:39 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml	1970-01-01 00:00:00 +0000
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.574436</TM>
-<Q>edge site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="edge" original_value="gobuntu"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI" original_value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context>
-<title>Launchpad Search Engine</title>
-</Context>
-<RES SN="1" EN="2">
-
-<M>2</M>
-<FI/>
-<NB>
-<NU>/custom?q=gobuntu+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=20&amp;sa=N</NU>
-</NB>
-
-<R N="1">
-<!-- Non public URL -->
-<T>Blueprint: &lt;b&gt;gobuntu&lt;/b&gt; hardy</T>
-<RK>0</RK>
-<S>Discuss what needs to be done for &lt;b&gt;Gobuntu&lt;/b&gt; and what can be achieved in the Hardy &lt;br&gt;  time frame. Read the full specification » &lt;b&gt;...&lt;/b&gt;</S>
-<LANG>en</LANG>
-<Label>_cse_ixpjdn21yfg</Label>
-<HAS>
-<L/>
-<RT/>
-</HAS>
-</R>
-
-<R N="2">
-<U>https://blueprints.launchpad.net/ubuntu/+spec/gobuntu-hardy</U>
-<UE>https://blueprints.launchpad.net/ubuntu/%2Bspec/gobuntu-hardy</UE>
-<T>Blueprint: &lt;b&gt;Gobuntu&lt;/b&gt; 8.04</T>
-<RK>0</RK>
-<S>Discuss what needs to be done for &lt;b&gt;Gobuntu&lt;/b&gt; and what can be achieved in the Hardy &lt;br&gt;  time frame. Read the full specification » &lt;b&gt;...&lt;/b&gt;</S>
-<LANG>en</LANG>
-<Label>_cse_ixpjdn21yfg</Label>
-<HAS>
-<L/>
-<C SZ="17k" CID="3PPx0kdgdSsJ"/>
-<RT/>
-</HAS>
-</R>
-
-</RES>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml	2010-12-01 19:30:04 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml	1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.3">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context>
-
-<RES SN="1" EN="1">
-<M>-1</M>
-<FI/><NB><NU>/custom?q=bugs+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=0&amp;sa=N</NU>
-</NB>
-
-<R N="1">
-  <U>https://bugs.launchpad.net/</U>
-  <UE>https://bugs.launchpad.net/</UE>
-  <T>A Title</T>
-  <RK>0</RK>
-  <CRAWLDATE>17 hours ago</CRAWLDATE>
-  <S>A 'R'esult.</S>
-  <LANG>en</LANG>
-  <Label>_cse_ixpjdn21yfg</Label>
-  <HAS><L/><RT/></HAS>
-</R>
-
-</RES>
-</GSP>

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml	2008-12-05 19:41:05 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml	1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.3">
-<TM>0.416786</TM><Q>no-meaning site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="no-meaning" original_value="no-meaning"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context>
-
-<RES SN="1" EN="1">
-<M>1</M>
-<FI/><NB><NU>/custom?q=bugs+site:launchpad.net&amp;num=20&amp;hl=en&amp;output=xml_no_dtd&amp;client=google-csbe&amp;cx=011948274177882366108:ixpjdn21yfg&amp;ie=UTF-8&amp;oe=UTF-8&amp;start=0&amp;sa=N</NU>
-</NB>
-
-<R N="1">
-  <U>https://bugs.launchpad.net/</U>
-  <UE>https://bugs.launchpad.net/</UE>
-  <T></T>
-  <RK>0</RK>
-  <CRAWLDATE>17 hours ago</CRAWLDATE>
-  <S>This 'R'esult does not have a title.</S>
-  <LANG>en</LANG>
-  <Label>_cse_ixpjdn21yfg</Label>
-  <HAS><L/><RT/></HAS>
-</R>
-
-</RES>
-</GSP>

=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml'
--- lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml	2008-05-15 21:58:33 +0000
+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<GSP VER="3.2">
-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
-<PARAM name="ie" value="utf8" original_value="utf8"/>
-<PARAM name="num" value="20" original_value="20"/>
-<PARAM name="oe" value="utf8" original_value="utf8"/>
-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
-<PARAM name="q" value="bugs" original_value="bugs"/>
-<PARAM name="start" value="0" original_value="0"/>
-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
-<PARAM name="hl" value="en" original_value="en"/>
-<Context><title>Launchpad Search Engine</title></Context>
-</GSP>
-

=== removed file 'lib/lp/services/sitesearch/tests/googleserviceharness.py'
--- lib/lp/services/sitesearch/tests/googleserviceharness.py	2018-03-28 17:00:10 +0000
+++ lib/lp/services/sitesearch/tests/googleserviceharness.py	1970-01-01 00:00:00 +0000
@@ -1,107 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""
-Fixtures for running the Google test webservice.
-"""
-
-__metaclass__ = type
-
-__all__ = ['GoogleServiceTestSetup']
-
-
-import errno
-import os
-import signal
-
-from lp.services.sitesearch import googletestservice
-
-
-class GoogleServiceTestSetup:
-    """Set up the Google web service stub for use in functional tests.
-    """
-
-    # XXX gary 2008-12-06 bug=305858: Spurious test failures discovered on
-    # buildbot, builds 40 and 43. The locations of the failures are marked
-    # below with " # SPURIOUS FAILURE". To reinstate, add the text below back
-    # to the docstring above.  Note that the test that uses this setup,
-    # google-service-stub.txt, is also disabled.  See test_doc.py.
-    """
-    >>> from lp.services.sitesearch.googletestservice import (
-    ...     service_is_available)
-    >>> from lp.services.config import config
-
-    >>> assert not service_is_available()  # Sanity check. # SPURIOUS FAILURE
-
-    >>> GoogleServiceTestSetup().setUp()
-
-    After setUp is called, a Google test service instance is running.
-
-    >>> assert service_is_available()
-    >>> assert GoogleServiceTestSetup.service is not None
-
-    After tearDown is called, the service is shut down.
-
-    >>> GoogleServiceTestSetup().tearDown()
-
-    >>> assert not service_is_available()
-    >>> assert GoogleServiceTestSetup.service is None
-
-    The fixture can be started and stopped multiple time in succession:
-
-    >>> GoogleServiceTestSetup().setUp()
-    >>> assert service_is_available()
-
-    Having a service instance already running doesn't prevent a new
-    service from starting.  The old instance is killed off and replaced
-    by the new one.
-
-    >>> old_pid = GoogleServiceTestSetup.service.pid
-    >>> GoogleServiceTestSetup().setUp() # SPURIOUS FAILURE
-    >>> GoogleServiceTestSetup.service.pid != old_pid
-    True
-
-    Tidy up.
-
-    >>> GoogleServiceTestSetup().tearDown()
-    >>> assert not service_is_available()
-
-    """
-
-    service = None  # A reference to our running service.
-
-    def setUp(self):
-        self.startService()
-
-    def tearDown(self):
-        self.stopService()
-
-    @classmethod
-    def startService(cls):
-        """Start the webservice."""
-        googletestservice.kill_running_process()
-        cls.service = googletestservice.start_as_process()
-        assert cls.service, "The Search service process did not start."
-        try:
-            googletestservice.wait_for_service()
-        except RuntimeError:
-            # The service didn't start itself soon enough.  We must
-            # make sure to kill any errant processes that may be
-            # hanging around.
-            cls.stopService()
-            raise
-
-    @classmethod
-    def stopService(cls):
-        """Shut down the webservice instance."""
-        if cls.service:
-            try:
-                os.kill(cls.service.pid, signal.SIGTERM)
-            except OSError as error:
-                if error.errno != errno.ESRCH:
-                    raise
-                # The process with the given pid doesn't exist, so there's
-                # nothing to kill or wait for.
-            else:
-                cls.service.wait()
-        cls.service = None

=== removed file 'lib/lp/services/sitesearch/tests/test_google.py'
--- lib/lp/services/sitesearch/tests/test_google.py	2018-04-16 18:43:52 +0000
+++ lib/lp/services/sitesearch/tests/test_google.py	1970-01-01 00:00:00 +0000
@@ -1,304 +0,0 @@
-# Copyright 2011-2016 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test the google search service."""
-
-from __future__ import absolute_import, print_function, unicode_literals
-
-__metaclass__ = type
-
-import os.path
-
-from fixtures import MockPatch
-from requests.exceptions import (
-    ConnectionError,
-    HTTPError,
-    )
-from testtools.matchers import (
-    HasLength,
-    MatchesListwise,
-    MatchesStructure,
-    )
-
-from lp.services.config import config
-from lp.services.sitesearch import GoogleSearchService
-from lp.services.sitesearch.interfaces import (
-    GoogleWrongGSPVersion,
-    SiteSearchResponseError,
-    )
-from lp.services.timeout import TimeoutError
-from lp.testing import TestCase
-from lp.testing.layers import GoogleLaunchpadFunctionalLayer
-
-
-class TestGoogleSearchService(TestCase):
-    """Test GoogleSearchService."""
-
-    layer = GoogleLaunchpadFunctionalLayer
-
-    def setUp(self):
-        super(TestGoogleSearchService, self).setUp()
-        self.search_service = GoogleSearchService()
-        self.base_path = os.path.normpath(
-            os.path.join(os.path.dirname(__file__), 'data'))
-
-    def test_configuration(self):
-        self.assertEqual(config.google.site, self.search_service.site)
-        self.assertEqual(
-            config.google.client_id, self.search_service.client_id)
-
-    def test_create_search_url(self):
-        self.assertEndsWith(
-            self.search_service.create_search_url(terms='svg +bugs'),
-            '&q=svg+%2Bbugs&start=0')
-
-    def test_create_search_url_escapes_unicode_chars(self):
-        self.assertEndsWith(
-            self.search_service.create_search_url(
-                'Carlos Perell\xf3 Mar\xedn'),
-            '&q=Carlos+Perell%C3%B3+Mar%C3%ADn&start=0')
-
-    def test_create_search_url_with_offset(self):
-        self.assertEndsWith(
-            self.search_service.create_search_url(terms='svg +bugs', start=20),
-            '&q=svg+%2Bbugs&start=20')
-
-    def test_create_search_url_empty_terms(self):
-        self.assertRaisesWithContent(
-            ValueError, "Missing value for parameter 'q'.",
-            self.search_service.create_search_url, '')
-
-    def test_create_search_url_null_terms(self):
-        self.assertRaisesWithContent(
-            ValueError, "Missing value for parameter 'q'.",
-            self.search_service.create_search_url, None)
-
-    def test_create_search_url_requires_start(self):
-        self.assertRaisesWithContent(
-            ValueError, "Value for parameter 'start' is not an int.",
-            self.search_service.create_search_url, 'bugs', 'true')
-
-    def test_parse_search_response_incompatible_param(self):
-        """The PageMatches's start attribute comes from the GSP XML element
-        '<PARAM name="start" value="0" original_value="0"/>'. When it cannot
-        be found and the value cast to an int, an error is raised. There is
-        nothing in the value attribute in the next test, so an error is raised.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-incompatible-param.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-        self.assertNotIn('<M>', response)
-
-        self.assertRaisesWithContent(
-            GoogleWrongGSPVersion,
-            "Could not get the 'start' from the GSP XML response.",
-            self.search_service._parse_search_response, response)
-
-    def test_parse_search_response_invalid_total(self):
-        """The PageMatches's total attribute comes from the GSP XML element
-        '<M>5</M>'. When it cannot be found and the value cast to an int,
-        an error is raised. If Google were to redefine the meaning of the M
-        element to use a '~' to indicate an approximate total, an error would
-        be raised.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-incompatible-matches.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-        self.assertIn('<M>~1</M>', response)
-
-        self.assertRaisesWithContent(
-            GoogleWrongGSPVersion,
-            "Could not get the 'total' from the GSP XML response.",
-            self.search_service._parse_search_response, response)
-
-    def test_parse_search_response_negative_total(self):
-        """If the total is ever less than zero (see bug 683115),
-        this is expected: we simply return a total of 0.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-negative-total.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-        self.assertIn('<M>-1</M>', response)
-
-        matches = self.search_service._parse_search_response(response)
-        self.assertEqual(0, matches.total)
-
-    def test_parse_search_response_missing_title(self):
-        """A PageMatch requires a title, url, and a summary. If those elements
-        ('<T>', '<U>', '<S>') cannot be found nested in an '<R>' a PageMatch
-        cannot be made. A missing title (<T>) indicates a bad page on Launchpad
-        so it is ignored. In this example, The first match is missing a title,
-        so only the second page is present in the PageMatches.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-missing-title.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-
-        matches = self.search_service._parse_search_response(response)
-        self.assertThat(matches, MatchesListwise([
-            MatchesStructure.byEquality(
-                title=(
-                    u'Bug #205991 in Ubuntu: \u201cCan&#39;t pair '
-                    u'Bluetooth Logitech DiNovo <b>Edge</b> <b>...</b>'),
-                url='http://bugs.launchpad.dev/bugs/205991'),
-            ]))
-
-    def test_parse_search_response_missing_summary(self):
-        """When a match is missing a summary (<S>), it is skipped because
-        there is no information about why it matched. This appears to relate to
-        pages that are in the index, but should be removed. In this example
-        taken from real data, the links are to the same page on different
-        vhosts. The edge vhost has no summary, so it is skipped.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-missing-summary.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-
-        matches = self.search_service._parse_search_response(response)
-        self.assertThat(matches, MatchesListwise([
-            MatchesStructure.byEquality(
-                title='Blueprint: <b>Gobuntu</b> 8.04',
-                url=(
-                    'http://blueprints.launchpad.dev'
-                    '/ubuntu/+spec/gobuntu-hardy')),
-            ]))
-
-    def test_parse_search_response_missing_url(self):
-        """When the URL (<U>) cannot be found the match is skipped. There are
-        no examples of this. We do not want this hypothetical situation to give
-        users a bad experience.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-missing-url.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-
-        matches = self.search_service._parse_search_response(response)
-        self.assertThat(matches, MatchesListwise([
-            MatchesStructure.byEquality(
-                title='Blueprint: <b>Gobuntu</b> 8.04',
-                url=(
-                    'http://blueprints.launchpad.dev'
-                    '/ubuntu/+spec/gobuntu-hardy')),
-            ]))
-
-    def test_parse_search_response_with_no_meaningful_results(self):
-        """If no matches are found in the response, and there are 20 or fewer
-        results, an Empty PageMatches is returned. This happens when the
-        results are missing titles and summaries. This is not considered to be
-        a problem because the small number implies that Google did a poor job
-        of indexing pages or indexed the wrong Launchpad server. In this
-        example, there is only one match, but the results is missing a title so
-        there is not enough information to make a PageMatch.
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-no-meaningful-results.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-        self.assertIn('<M>1</M>', response)
-
-        matches = self.search_service._parse_search_response(response)
-        self.assertThat(matches, HasLength(0))
-
-    def test_parse_search_response_with_incompatible_result(self):
-        """If no matches are found in the response, and there are more than 20
-        possible matches, an error is raised. Unlike the previous example there
-        are lots of results; there is a possibility that the GSP version is
-        incompatible. This example says it has 1000 matches, but none of the R
-        tags can be parsed (because the markup was changed to use RESULT).
-        """
-        file_name = os.path.join(
-            self.base_path, 'googlesearchservice-incompatible-result.xml')
-        with open(file_name, 'r') as response_file:
-            response = response_file.read()
-        self.assertIn('<M>1000</M>', response)
-
-        self.assertRaisesWithContent(
-            GoogleWrongGSPVersion,
-            "Could not get any PageMatches from the GSP XML response.",
-            self.search_service._parse_search_response, response)
-
-    def test_search_converts_HTTPError(self):
-        # The method converts HTTPError to SiteSearchResponseError.
-        args = ('url', 500, 'oops', {}, None)
-        self.useFixture(MockPatch(
-            'lp.services.sitesearch.urlfetch', side_effect=HTTPError(*args)))
-        self.assertRaises(
-            SiteSearchResponseError, self.search_service.search, 'fnord')
-
-    def test_search_converts_ConnectionError(self):
-        # The method converts ConnectionError to SiteSearchResponseError.
-        self.useFixture(MockPatch(
-            'lp.services.sitesearch.urlfetch',
-            side_effect=ConnectionError('oops')))
-        self.assertRaises(
-            SiteSearchResponseError, self.search_service.search, 'fnord')
-
-    def test_search_converts_TimeoutError(self):
-        # The method converts TimeoutError to SiteSearchResponseError.
-        self.useFixture(MockPatch(
-            'lp.services.sitesearch.urlfetch',
-            side_effect=TimeoutError('oops')))
-        self.assertRaises(
-            SiteSearchResponseError, self.search_service.search, 'fnord')
-
-    def test_parse_search_response_SyntaxError(self):
-        # The method converts SyntaxError to SiteSearchResponseError.
-        self.useFixture(MockPatch(
-            'lp.services.sitesearch.urlfetch',
-            side_effect=SyntaxError('oops')))
-        self.assertRaises(
-            SiteSearchResponseError,
-            self.search_service._parse_search_response, '')
-
-    def test_parse_search_response_IndexError(self):
-        # The method converts IndexError to SiteSearchResponseError.
-        self.useFixture(MockPatch(
-            'lp.services.sitesearch.urlfetch', side_effect=IndexError('oops')))
-        data = (
-            '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
-            '<GSP VER="3.2"></GSP>')
-        self.assertRaises(
-            SiteSearchResponseError,
-            self.search_service._parse_search_response, data)
-
-    def test_search_with_results(self):
-        matches = self.search_service.search('bug')
-        self.assertEqual(0, matches.start)
-        self.assertEqual(25, matches.total)
-        self.assertEqual(20, len(matches))
-
-    def test_search_with_results_and_offset(self):
-        matches = self.search_service.search('bug', start=20)
-        self.assertEqual(20, matches.start)
-        self.assertEqual(25, matches.total)
-        self.assertEqual(5, len(matches))
-        self.assertEqual([
-            'http://bugs.launchpad.dev/ubuntu/hoary/+bug/2',
-            'http://bugs.launchpad.dev/debian/+source/mozilla-firefox/+bug/2',
-            'http://bugs.launchpad.dev/debian/+source/mozilla-firefox/+bug/3',
-            'http://bugs.launchpad.dev/bugs/bugtrackers',
-            'http://bugs.launchpad.dev/bugs/bugtrackers/debbugs'],
-            [match.url for match in matches])
-
-    def test_search_no_results(self):
-        matches = self.search_service.search('fnord')
-        self.assertEqual(0, matches.start)
-        self.assertEqual(0, matches.total)
-        self.assertEqual(0, len(matches))
-
-    def test_search_no_meaningful_results(self):
-        matches = self.search_service.search('no-meaningful')
-        self.assertEqual(0, matches.start)
-        self.assertEqual(1, matches.total)
-        self.assertEqual(0, len(matches))
-
-    def test_search_incomplete_response(self):
-        self.assertRaises(
-            SiteSearchResponseError,
-            self.search_service.search, 'gnomebaker')

=== removed file 'lib/lp/services/sitesearch/tests/test_googleharness.py'
--- lib/lp/services/sitesearch/tests/test_googleharness.py	2018-03-16 14:02:16 +0000
+++ lib/lp/services/sitesearch/tests/test_googleharness.py	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-import doctest
-
-
-def test_suite():
-    return doctest.DocTestSuite(
-            'lp.services.sitesearch.tests.googleserviceharness',
-            optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS)

=== modified file 'lib/lp/services/sitesearch/tests/test_testservices.py'
--- lib/lp/services/sitesearch/tests/test_testservices.py	2018-04-13 20:26:48 +0000
+++ lib/lp/services/sitesearch/tests/test_testservices.py	2018-05-21 21:36:59 +0000
@@ -15,10 +15,7 @@
 
 from lp.services.osutils import process_exists
 from lp.services.pidfile import pidfile_path
-from lp.services.sitesearch import (
-    bingtestservice,
-    googletestservice,
-    )
+from lp.services.sitesearch import bingtestservice
 
 
 class TestServiceUtilities(WithScenarios, unittest.TestCase):
@@ -28,9 +25,6 @@
         ("Bing", {
             "testservice": bingtestservice,
             }),
-        ("Google", {
-            "testservice": googletestservice,
-            }),
         ]
 
     def test_stale_pid_file_cleanup(self):

=== modified file 'lib/lp/testing/layers.py'
--- lib/lp/testing/layers.py	2018-03-27 20:45:52 +0000
+++ lib/lp/testing/layers.py	2018-05-21 21:36:59 +0000
@@ -28,8 +28,6 @@
     'DatabaseFunctionalLayer',
     'DatabaseLayer',
     'FunctionalLayer',
-    'GoogleLaunchpadFunctionalLayer',
-    'GoogleServiceLayer',
     'LaunchpadFunctionalLayer',
     'LaunchpadLayer',
     'LaunchpadScriptLayer',
@@ -131,9 +129,6 @@
 from lp.services.sitesearch.tests.bingserviceharness import (
     BingServiceTestSetup,
     )
-from lp.services.sitesearch.tests.googleserviceharness import (
-    GoogleServiceTestSetup,
-    )
 from lp.services.testing.profiled import profiled
 from lp.services.timeout import (
     get_default_timeout_function,
@@ -1239,31 +1234,6 @@
         TwistedLayer._restore_signals()
 
 
-class GoogleServiceLayer(BaseLayer):
-    """Tests for Google web service integration."""
-
-    @classmethod
-    def setUp(cls):
-        google = GoogleServiceTestSetup()
-        google.setUp()
-
-    @classmethod
-    def tearDown(cls):
-        GoogleServiceTestSetup().tearDown()
-
-    @classmethod
-    def testSetUp(self):
-        # We need to override BaseLayer.testSetUp(), or else we will
-        # get a LayerIsolationError.
-        pass
-
-    @classmethod
-    def testTearDown(self):
-        # We need to override BaseLayer.testTearDown(), or else we will
-        # get a LayerIsolationError.
-        pass
-
-
 class BingServiceLayer(BaseLayer):
     """Tests for Bing web service integration."""
 
@@ -1388,31 +1358,6 @@
         pass
 
 
-class GoogleLaunchpadFunctionalLayer(LaunchpadFunctionalLayer,
-                                     GoogleServiceLayer):
-    """Provides Google service in addition to LaunchpadFunctionalLayer."""
-
-    @classmethod
-    @profiled
-    def setUp(cls):
-        pass
-
-    @classmethod
-    @profiled
-    def tearDown(cls):
-        pass
-
-    @classmethod
-    @profiled
-    def testSetUp(cls):
-        pass
-
-    @classmethod
-    @profiled
-    def testTearDown(cls):
-        pass
-
-
 class BingLaunchpadFunctionalLayer(LaunchpadFunctionalLayer,
                                    BingServiceLayer):
     """Provides Bing service in addition to LaunchpadFunctionalLayer."""
@@ -1596,8 +1541,7 @@
         return self.request._orig_env
 
 
-class PageTestLayer(LaunchpadFunctionalLayer,
-                    BingServiceLayer, GoogleServiceLayer):
+class PageTestLayer(LaunchpadFunctionalLayer, BingServiceLayer):
     """Environment for page tests.
     """
 

=== modified file 'setup.py'
--- setup.py	2018-05-06 08:52:34 +0000
+++ setup.py	2018-05-21 21:36:59 +0000
@@ -291,8 +291,6 @@
             'build-twisted-plugin-cache = '
                 'lp.services.twistedsupport.plugincache:main',
             'combine-css = lp.scripts.utilities.js.combinecss:main',
-            'googletestservice = '
-                'lp.services.sitesearch.googletestservice:main',
             'harness = lp.scripts.harness:python',
             'iharness = lp.scripts.harness:ipython',
             'ipy = IPython.frontend.terminal.ipapp:launch_new_instance',

_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : launchpad-reviewers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to