Merge lp:~maxiberta/launchpad/sitesearch-drop-google-backend into lp:launchpad

Proposed by Maximiliano Bertacchini
Status: Merged
Merged at revision: 18662
Proposed branch: lp:~maxiberta/launchpad/sitesearch-drop-google-backend
Merge into: lp:launchpad
Diff against target: 1828 lines (+17/-1341)
34 files modified
Makefile (+0/-1)
configs/development/launchpad-lazr.conf (+0/-8)
configs/testrunner-appserver/launchpad-lazr.conf (+0/-3)
configs/testrunner/launchpad-lazr.conf (+0/-5)
lib/lp/app/browser/doc/launchpad-search-pages.txt (+11/-14)
lib/lp/app/browser/tests/test_views.py (+0/-18)
lib/lp/app/tests/test_doc.py (+0/-16)
lib/lp/scripts/runlaunchpad.py (+1/-15)
lib/lp/scripts/tests/test_runlaunchpad.py (+1/-3)
lib/lp/services/config/schema-lazr.conf (+0/-25)
lib/lp/services/features/flags.py (+2/-2)
lib/lp/services/sitesearch/__init__.py (+0/-179)
lib/lp/services/sitesearch/configure.zcml (+0/-7)
lib/lp/services/sitesearch/googletestservice.py (+0/-82)
lib/lp/services/sitesearch/interfaces.py (+0/-5)
lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml (+0/-63)
lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml (+0/-33)
lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml (+0/-36)
lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml (+0/-18)
lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml (+0/-36)
lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml (+0/-1)
lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt (+0/-24)
lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml (+0/-58)
lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml (+0/-58)
lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml (+0/-57)
lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml (+0/-35)
lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml (+0/-35)
lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml (+0/-17)
lib/lp/services/sitesearch/tests/googleserviceharness.py (+0/-107)
lib/lp/services/sitesearch/tests/test_google.py (+0/-304)
lib/lp/services/sitesearch/tests/test_googleharness.py (+0/-10)
lib/lp/services/sitesearch/tests/test_testservices.py (+1/-7)
lib/lp/testing/layers.py (+1/-57)
setup.py (+0/-2)
To merge this branch: bzr merge lp:~maxiberta/launchpad/sitesearch-drop-google-backend
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+346425@code.launchpad.net

Commit message

Remove the Google search service backend.

Description of the change

Remove the Google search service backend, leaving all the generic boilerplate to make adding a new search engine easier next time.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2018-04-02 16:40:03 +0000
3+++ Makefile 2018-05-21 21:36:59 +0000
4@@ -64,7 +64,6 @@
5 bin/bingtestservice \
6 bin/build-twisted-plugin-cache \
7 bin/combine-css \
8- bin/googletestservice \
9 bin/harness \
10 bin/iharness \
11 bin/ipy \
12
13=== modified file 'configs/development/launchpad-lazr.conf'
14--- configs/development/launchpad-lazr.conf 2018-03-26 18:59:34 +0000
15+++ configs/development/launchpad-lazr.conf 2018-05-21 21:36:59 +0000
16@@ -78,14 +78,6 @@
17 oops_prefix: X
18 error_dir: /var/tmp/lperr
19
20-[google]
21-# Development and the testrunner should use the stub service by default.
22-site: http://launchpad.dev:8092/cse
23-client_id: ABCDEF2323
24-
25-[google_test_service]
26-launch: True
27-
28 [bing]
29 # Development and the testrunner should use the stub service by default.
30 site: http://launchpad.dev:8093/bingcustomsearch/v7.0/search
31
32=== modified file 'configs/testrunner-appserver/launchpad-lazr.conf'
33--- configs/testrunner-appserver/launchpad-lazr.conf 2018-03-16 21:04:45 +0000
34+++ configs/testrunner-appserver/launchpad-lazr.conf 2018-05-21 21:36:59 +0000
35@@ -11,9 +11,6 @@
36 [codeimport]
37 macaroon_secret_key: dev-macaroon-secret
38
39-[google_test_service]
40-launch: False
41-
42 [bing_test_service]
43 launch: False
44
45
46=== modified file 'configs/testrunner/launchpad-lazr.conf'
47--- configs/testrunner/launchpad-lazr.conf 2018-03-16 21:04:45 +0000
48+++ configs/testrunner/launchpad-lazr.conf 2018-05-21 21:36:59 +0000
49@@ -88,9 +88,6 @@
50 source_only: True
51 root: /tmp/gina_test_archive
52
53-[google]
54-site: http://launchpad.dev:8092/cse
55-
56 [bing]
57 site: http://launchpad.dev:8093/bingcustomsearch/v7.0/search
58
59@@ -108,8 +105,6 @@
60 max_attachment_size: 1024
61 geoip_database: /usr/share/GeoIP/GeoLiteCity.dat
62 logparser_max_parsed_lines: 100000
63-# We use the stub Google Service here which maps URL fragment to
64-# to static content
65 homepage_recent_posts_feed: http://launchpad.dev:8092/blog-feed
66 openid_canonical_root: http://testopenid.dev/
67 openid_provider_root: http://testopenid.dev/
68
69=== modified file 'lib/lp/app/browser/doc/launchpad-search-pages.txt'
70--- lib/lp/app/browser/doc/launchpad-search-pages.txt 2018-04-13 21:57:12 +0000
71+++ lib/lp/app/browser/doc/launchpad-search-pages.txt 2018-05-21 21:36:59 +0000
72@@ -406,7 +406,7 @@
73 Page searches
74 -------------
75
76-The view uses the GoogleSearchService to locate pages that match the
77+The view uses the Search Service to locate pages that match the
78 search terms.
79
80 >>> search_view = getSearchView(
81@@ -418,23 +418,23 @@
82 >>> search_view.pages
83 <...SiteSearchBatchNavigator ...>
84
85-The GoogleSearchService may not be available due to connectivity problems.
86+The Search Service may not be available due to connectivity problems.
87 The view's has_page_service attribute reports when the search was performed
88-with Google page matches.
89+with the Search Service page matches.
90
91 >>> search_view.has_page_service
92 True
93
94 The batch navigation heading is created by the view. The heading
95 property returns a 2-tuple of singular and plural heading. There
96-is a heading when there are only Google page matches...
97+is a heading when there are only Search Service page matches...
98
99 >>> search_view.has_exact_matches
100 False
101 >>> search_view.batch_heading
102 (u'page matching "bug"', u'pages matching "bug"')
103
104-...and a heading for when there are exact matches and Google page
105+...and a heading for when there are exact matches and Search Service page
106 matches.
107
108 >>> search_view = getSearchView(
109@@ -518,14 +518,11 @@
110 >>> page.summary
111 u'...Launchpad\u2019s ...bug... tracker allows collaboration...'
112
113-See `google-searchservice.txt` for more information about the
114-GoogleSearchService and PageMatch objects.
115-
116
117 No page matches
118 ---------------
119
120-When an empty PageMatches object is returned by the GoogleSearchService to
121+When an empty PageMatches object is returned by the Search Service to
122 the view, there are no matches to show.
123
124 >>> search_view = getSearchView(form={'field.text': 'no-meaningful'})
125@@ -549,11 +546,11 @@
126 True
127
128
129-Bad Google response handling
130+Bad site search response handling
131 ----------------------------
132
133 Connectivity problems can cause missing or incomplete responses from
134-Google. The LaunchpadSearchView will display the other searches and
135+the site search engine. The LaunchpadSearchView will display the other searches and
136 show a message explaining that the user can search again to find
137 matching pages.
138
139@@ -631,7 +628,7 @@
140 The LaunchpadSearchView uses two helper classes to work with
141 PageMatches.
142
143-The PageMatches object returned by the GoogleSearchService contains 20
144+The PageMatches object returned by the Search Service contains 20
145 or fewer PageMatches of what could be thousands of matches. Google
146 requires client's to make repeats request to step though the batches of
147 matches. The Windowed list is a list that contains only a subset of its
148@@ -661,7 +658,7 @@
149
150 The SiteSearchBatchNavigator restricts the batch size to 20. the 'batch'
151 parameter that comes from the URL is ignored. For example, setting
152-the 'batch' parameter to 100 has no affect upon the Google search
153+the 'batch' parameter to 100 has no affect upon the site search
154 or on the navigator object.
155
156 >>> from lp.app.browser.root import SiteSearchBatchNavigator
157@@ -699,7 +696,7 @@
158 '...start=20'
159
160 The PageMatches object can be smaller than 20, for instance, pages
161-without titles are skipped when parsing the Google Search XML. The size
162+without titles are skipped when parsing the search engine response. The size
163 of the batch is still 20, but when the items in the batch are iterated,
164 the true size can be seen. For example there could be only 3 matches in
165 the PageMatches object, so only 3 are yielded. The start of the next
166
167=== modified file 'lib/lp/app/browser/tests/test_views.py'
168--- lib/lp/app/browser/tests/test_views.py 2018-04-13 21:57:12 +0000
169+++ lib/lp/app/browser/tests/test_views.py 2018-05-21 21:36:59 +0000
170@@ -14,7 +14,6 @@
171 from lp.services.testing import build_test_suite
172 from lp.testing.layers import (
173 BingLaunchpadFunctionalLayer,
174- GoogleLaunchpadFunctionalLayer,
175 PageTestLayer,
176 )
177 from lp.testing.systemdocs import (
178@@ -26,7 +25,6 @@
179
180 here = os.path.dirname(os.path.realpath(__file__))
181 bing_flag = FeatureFixture({'sitesearch.engine.name': 'bing'})
182-google_flag = FeatureFixture({'sitesearch.engine.name': 'google'})
183
184
185 def setUp_bing(test):
186@@ -34,21 +32,11 @@
187 bing_flag.setUp()
188
189
190-def setUp_google(test):
191- setUp(test)
192- google_flag.setUp()
193-
194-
195 def tearDown_bing(test):
196 bing_flag.cleanUp()
197 tearDown(test)
198
199
200-def tearDown_google(test):
201- google_flag.cleanUp()
202- tearDown(test)
203-
204-
205 # The default layer of view tests is the DatabaseFunctionalLayer. Tests
206 # that require something special like the librarian or mailman must run
207 # on a layer that sets those services up.
208@@ -59,12 +47,6 @@
209 setUp=setUp_bing, tearDown=tearDown_bing,
210 layer=BingLaunchpadFunctionalLayer,
211 stdout_logging_level=logging.WARNING),
212- 'launchpad-search-pages.txt(Google)': LayeredDocFileSuite(
213- '../doc/launchpad-search-pages.txt',
214- id_extensions=['launchpad-search-pages.txt(Google)'],
215- setUp=setUp_google, tearDown=tearDown_google,
216- layer=GoogleLaunchpadFunctionalLayer,
217- stdout_logging_level=logging.WARNING),
218 # Run these doctests again with the default search engine.
219 'launchpad-search-pages.txt': LayeredDocFileSuite(
220 '../doc/launchpad-search-pages.txt',
221
222=== modified file 'lib/lp/app/tests/test_doc.py'
223--- lib/lp/app/tests/test_doc.py 2018-04-13 20:47:03 +0000
224+++ lib/lp/app/tests/test_doc.py 2018-05-21 21:36:59 +0000
225@@ -23,7 +23,6 @@
226
227 here = os.path.dirname(os.path.realpath(__file__))
228 bing_flag = FeatureFixture({'sitesearch.engine.name': 'bing'})
229-google_flag = FeatureFixture({'sitesearch.engine.name': 'google'})
230
231
232 def setUp_bing(test):
233@@ -31,21 +30,11 @@
234 bing_flag.setUp()
235
236
237-def setUp_google(test):
238- setUpGlobs(test)
239- google_flag.setUp()
240-
241-
242 def tearDown_bing(test):
243 bing_flag.cleanUp()
244 tearDown(test)
245
246
247-def tearDown_google(test):
248- google_flag.cleanUp()
249- tearDown(test)
250-
251-
252 special = {
253 'tales.txt': LayeredDocFileSuite(
254 '../doc/tales.txt',
255@@ -60,11 +49,6 @@
256 id_extensions=['site-search.txt(Bing)'],
257 setUp=setUp_bing, tearDown=tearDown_bing,
258 ),
259- 'stories/launchpad-search(Google)': PageTestSuite(
260- '../stories/launchpad-search/',
261- id_extensions=['site-search.txt(Google)'],
262- setUp=setUp_google, tearDown=tearDown_google,
263- ),
264 # Run these doctests again with the default search engine.
265 '../stories/launchpad-search': PageTestSuite(
266 '../stories/launchpad-search/',
267
268=== modified file 'lib/lp/scripts/runlaunchpad.py'
269--- lib/lp/scripts/runlaunchpad.py 2018-03-16 21:04:45 +0000
270+++ lib/lp/scripts/runlaunchpad.py 2018-05-21 21:36:59 +0000
271@@ -26,10 +26,7 @@
272 pidfile_path,
273 )
274 from lp.services.rabbit.server import RabbitServer
275-from lp.services.sitesearch import (
276- bingtestservice,
277- googletestservice,
278- )
279+from lp.services.sitesearch import bingtestservice
280 from lp.services.txlongpoll.server import TxLongPollServer
281
282
283@@ -146,16 +143,6 @@
284 process.stdin.close()
285
286
287-class GoogleWebService(Service):
288-
289- @property
290- def should_launch(self):
291- return config.google_test_service.launch
292-
293- def launch(self):
294- self.addCleanup(stop_process, googletestservice.start_as_process())
295-
296-
297 class BingWebService(Service):
298
299 @property
300@@ -295,7 +282,6 @@
301 'mailman': MailmanService(),
302 'bing-webservice': BingWebService(),
303 'codebrowse': CodebrowseService(),
304- 'google-webservice': GoogleWebService(),
305 'memcached': MemcachedService(),
306 'rabbitmq': RabbitService(),
307 'txlongpoll': TxLongPollService(),
308
309=== modified file 'lib/lp/scripts/tests/test_runlaunchpad.py'
310--- lib/lp/scripts/tests/test_runlaunchpad.py 2018-03-29 14:41:36 +0000
311+++ lib/lp/scripts/tests/test_runlaunchpad.py 2018-05-21 21:36:59 +0000
312@@ -1,4 +1,4 @@
313-# Copyright 2009 Canonical Ltd. This software is licensed under the
314+# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
315 # GNU Affero General Public License version 3 (see the file LICENSE).
316
317 """Tests for runlaunchpad.py"""
318@@ -151,8 +151,6 @@
319 # run.
320 if config.bing_test_service.launch:
321 expected.append(SERVICES['bing-webservice'])
322- if config.google_test_service.launch:
323- expected.append(SERVICES['google-webservice'])
324
325 # RabbitMQ may or may not be asked to run.
326 if config.rabbitmq.launch:
327
328=== modified file 'lib/lp/services/config/schema-lazr.conf'
329--- lib/lp/services/config/schema-lazr.conf 2018-04-12 19:59:21 +0000
330+++ lib/lp/services/config/schema-lazr.conf 2018-05-21 21:36:59 +0000
331@@ -763,31 +763,6 @@
332 distroseries: experimental
333 pocketrelease: experimental
334
335-[google_test_service]
336-# Run a web service stub that simulates the Google search service.
337-
338-# Where are our canned XML responses stored?
339-canned_response_directory: lib/lp/services/sitesearch/tests/data/
340-
341-# Which file maps service URLs to the XML that the server returns?
342-mapfile: lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt
343-
344-# Where should the service log files live?
345-log: logs/google-stub.log
346-
347-# Do we actually want to run the service?
348-launch: False
349-
350-[google]
351-# client_id is the unique id Launchpad was issued by Google.
352-# datatype: string
353-client_id:
354-
355-# site is the host and path that search requests are made to.
356-# eg. http://www.google.com/cse
357-# datatype: string, a url to a host
358-site: http://www.google.com/cse
359-
360 [sitesearch]
361 # url_rewrite_exceptions is a list of launchpad.net domains that must
362 # not be rewritten.
363
364=== modified file 'lib/lp/services/features/flags.py'
365--- lib/lp/services/features/flags.py 2018-03-30 23:06:00 +0000
366+++ lib/lp/services/features/flags.py 2018-05-21 21:36:59 +0000
367@@ -1,4 +1,4 @@
368-# Copyright 2010-2016 Canonical Ltd. This software is licensed under the
369+# Copyright 2010-2018 Canonical Ltd. This software is licensed under the
370 # GNU Affero General Public License version 3 (see the file LICENSE).
371
372 __all__ = [
373@@ -236,7 +236,7 @@
374 ''),
375 ('sitesearch.engine.name',
376 'space delimited',
377- 'Name of the site search engine backend ("google" or "bing").',
378+ 'Name of the site search engine backend (only "bing" is available).',
379 'bing',
380 'Site search engine',
381 ''),
382
383=== modified file 'lib/lp/services/sitesearch/__init__.py'
384--- lib/lp/services/sitesearch/__init__.py 2018-04-12 19:59:21 +0000
385+++ lib/lp/services/sitesearch/__init__.py 2018-05-21 21:36:59 +0000
386@@ -7,7 +7,6 @@
387
388 __all__ = [
389 'BingSearchService',
390- 'GoogleSearchService',
391 'PageMatch',
392 'PageMatches',
393 ]
394@@ -18,7 +17,6 @@
395 parse_qsl,
396 urlunparse,
397 )
398-import xml.etree.cElementTree as ET
399
400 from lazr.restful.utils import get_current_browser_request
401 from lazr.uri import URI
402@@ -27,7 +25,6 @@
403
404 from lp.services.config import config
405 from lp.services.sitesearch.interfaces import (
406- GoogleWrongGSPVersion,
407 ISearchResult,
408 ISearchResults,
409 ISearchService,
410@@ -163,182 +160,6 @@
411
412
413 @implementer(ISearchService)
414-class GoogleSearchService:
415- """See `ISearchService`.
416-
417- A search service that searches Google for launchpad.net pages.
418- """
419-
420- _default_values = {
421- 'client': 'google-csbe',
422- 'cx': None,
423- 'ie': 'utf8',
424- 'num': 20,
425- 'oe': 'utf8',
426- 'output': 'xml_no_dtd',
427- 'start': 0,
428- 'q': None,
429- }
430-
431- @property
432- def client_id(self):
433- """The client-id issued by Google.
434-
435- Google requires that each client of the Google Search Engine
436- service to pass its id as a parameter in the request URL.
437- """
438- return config.google.client_id
439-
440- @property
441- def site(self):
442- """The URL to the Google Search Engine service.
443-
444- The URL is probably http://www.google.com/search.
445- """
446- return config.google.site
447-
448- def search(self, terms, start=0):
449- """See `ISearchService`.
450-
451- The config.google.client_id is used as Google client-id in the
452- search request. Search returns 20 or fewer results for each query.
453- For terms that match more than 20 results, the start param can be
454- used over multiple queries to get successive sets of results.
455-
456- :return: `ISearchResults` (PageMatches).
457- :raise: `GoogleWrongGSPVersion` if the xml cannot be parsed.
458- """
459- search_url = self.create_search_url(terms, start=start)
460- request = get_current_browser_request()
461- timeline = get_request_timeline(request)
462- action = timeline.start("google-search-api", search_url)
463- try:
464- response = urlfetch(search_url)
465- except (TimeoutError, requests.RequestException) as error:
466- # Google search service errors are not code errors. Let the
467- # call site choose to handle the unavailable service.
468- raise SiteSearchResponseError(
469- "The response errored: %s" % str(error))
470- finally:
471- action.finish()
472- page_matches = self._parse_search_response(response.content)
473- return page_matches
474-
475- def _checkParameter(self, name, value, is_int=False):
476- """Check that a parameter value is not None or an empty string."""
477- if value in (None, ''):
478- raise ValueError("Missing value for parameter '%s'." % name)
479- if is_int:
480- try:
481- int(value)
482- except ValueError:
483- raise ValueError(
484- "Value for parameter '%s' is not an int." % name)
485-
486- def create_search_url(self, terms, start=0):
487- """Return a Google search url."""
488- self._checkParameter('q', terms)
489- self._checkParameter('start', start, is_int=True)
490- self._checkParameter('cx', self.client_id)
491- search_params = dict(self._default_values)
492- search_params['q'] = terms.encode('utf8')
493- search_params['start'] = start
494- search_params['cx'] = self.client_id
495- query_string = urllib.urlencode(sorted(search_params.items()))
496- return self.site + '?' + query_string
497-
498- def _getElementsByAttributeValue(self, doc, path, name, value):
499- """Return a list of elements whose named attribute matches the value.
500-
501- The cElementTree implementation does not support attribute selection
502- (@) or conditional expressions (./PARAM[@name = 'start']).
503-
504- :param doc: An ElementTree of an XML document.
505- :param path: A string path to match the first element.
506- :param name: The attribute name to check.
507- :param value: The string value of the named attribute.
508- """
509- elements = doc.findall(path)
510- return [element for element in elements
511- if element.get(name) == value]
512-
513- def _getElementByAttributeValue(self, doc, path, name, value):
514- """Return the first element whose named attribute matches the value.
515-
516- :param doc: An ElementTree of an XML document.
517- :param path: A string path to match an element.
518- :param name: The attribute name to check.
519- :param value: The string value of the named attribute.
520- """
521- return self._getElementsByAttributeValue(doc, path, name, value)[0]
522-
523- def _parse_search_response(self, gsp_xml):
524- """Return a `PageMatches` object.
525-
526- :param gsp_xml: A string that should be Google Search Protocol
527- version 3.2 XML. There is no guarantee that other GSP versions
528- can be parsed.
529- :return: `ISearchResults` (PageMatches).
530- :raise: `SiteSearchResponseError` if the xml is incomplete.
531- :raise: `GoogleWrongGSPVersion` if the xml cannot be parsed.
532- """
533- try:
534- gsp_doc = ET.fromstring(gsp_xml)
535- start_param = self._getElementByAttributeValue(
536- gsp_doc, './PARAM', 'name', 'start')
537- except (SyntaxError, IndexError):
538- raise SiteSearchResponseError(
539- "The response was incomplete, no xml.")
540- try:
541- start = int(start_param.get('value'))
542- except (AttributeError, ValueError):
543- # The datatype is not what PageMatches requires.
544- raise GoogleWrongGSPVersion(
545- "Could not get the 'start' from the GSP XML response.")
546- page_matches = []
547- total = 0
548- results = gsp_doc.find('RES')
549- if results is None:
550- # Google did not match any pages. Return an empty PageMatches.
551- return PageMatches(page_matches, start, total)
552-
553- try:
554- total = int(results.find('M').text)
555- except (AttributeError, ValueError):
556- # The datatype is not what PageMatches requires.
557- raise GoogleWrongGSPVersion(
558- "Could not get the 'total' from the GSP XML response.")
559- if total < 0:
560- # See bug 683115.
561- total = 0
562- for result in results.findall('R'):
563- url_tag = result.find('U')
564- title_tag = result.find('T')
565- summary_tag = result.find('S')
566- if None in (url_tag, title_tag, summary_tag):
567- # Google indexed a bad page, or the page may be marked for
568- # removal from the index. We should not include this.
569- continue
570- title = title_tag.text
571- url = url_tag.text
572- summary = summary_tag.text
573- if None in (url, title, summary):
574- # There is not enough data to create a PageMatch object.
575- # This can be caused by an empty title or summary which
576- # has been observed for pages that are from vhosts that
577- # should not be indexed.
578- continue
579- summary = summary.replace('<br>', '')
580- page_matches.append(PageMatch(title, url, summary))
581- if len(page_matches) == 0 and total > 20:
582- # No viable page matches could be found in the set and there
583- # are more possible matches; the XML may be the wrong version.
584- raise GoogleWrongGSPVersion(
585- "Could not get any PageMatches from the GSP XML response.")
586- return PageMatches(page_matches, start, total)
587-
588-
589-@implementer(ISearchService)
590 class BingSearchService:
591 """See `ISearchService`.
592
593
594=== modified file 'lib/lp/services/sitesearch/configure.zcml'
595--- lib/lp/services/sitesearch/configure.zcml 2018-03-27 20:41:35 +0000
596+++ lib/lp/services/sitesearch/configure.zcml 2018-05-21 21:36:59 +0000
597@@ -16,13 +16,6 @@
598 </class>
599
600 <securedutility
601- name="google"
602- class="lp.services.sitesearch.GoogleSearchService"
603- provides="lp.services.sitesearch.interfaces.ISearchService">
604- <allow interface="lp.services.sitesearch.interfaces.ISearchService" />
605- </securedutility>
606-
607- <securedutility
608 name="bing"
609 class="lp.services.sitesearch.BingSearchService"
610 provides="lp.services.sitesearch.interfaces.ISearchService">
611
612=== removed file 'lib/lp/services/sitesearch/googletestservice.py'
613--- lib/lp/services/sitesearch/googletestservice.py 2018-04-12 20:04:28 +0000
614+++ lib/lp/services/sitesearch/googletestservice.py 1970-01-01 00:00:00 +0000
615@@ -1,82 +0,0 @@
616-#!/usr/bin/python
617-#
618-# Copyright 2018 Canonical Ltd. This software is licensed under the
619-# GNU Affero General Public License version 3 (see the file LICENSE).
620-
621-"""
622-This script runs a simple HTTP server. The server returns XML files
623-when given certain user-configurable URLs.
624-"""
625-from __future__ import absolute_import, print_function, unicode_literals
626-
627-__metaclass__ = type
628-
629-import logging
630-import os
631-
632-from six.moves.BaseHTTPServer import HTTPServer
633-
634-from lp.services.config import config
635-from lp.services.osutils import ensure_directory_exists
636-from lp.services.pidfile import make_pidfile
637-from lp.services.sitesearch import testservice
638-
639-
640-# Set up basic logging.
641-log = logging.getLogger(__name__)
642-
643-# The default service name, used by the Launchpad service framework.
644-service_name = 'google-webservice'
645-
646-
647-class GoogleRequestHandler(testservice.RequestHandler):
648- default_content_type = 'text/xml; charset=UTF-8'
649- log = log
650- mapfile = config.google_test_service.mapfile
651- content_dir = config.google_test_service.canned_response_directory
652-
653-
654-def start_as_process():
655- return testservice.start_as_process('googletestservice')
656-
657-
658-def get_service_endpoint():
659- """Return the host and port that the service is running on."""
660- return testservice.hostpair(config.google.site)
661-
662-
663-def service_is_available():
664- host, port = get_service_endpoint()
665- return testservice.service_is_available(host, port)
666-
667-
668-def wait_for_service():
669- host, port = get_service_endpoint()
670- return testservice.wait_for_service(host, port)
671-
672-
673-def kill_running_process():
674- global service_name
675- host, port = get_service_endpoint()
676- return testservice.kill_running_process(service_name, host, port)
677-
678-
679-def main():
680- """Run the HTTP server."""
681- # Redirect our service output to a log file.
682- global log
683- ensure_directory_exists(os.path.dirname(config.google_test_service.log))
684- filelog = logging.FileHandler(config.google_test_service.log)
685- log.addHandler(filelog)
686- log.setLevel(logging.DEBUG)
687-
688- # To support service shutdown we need to create a PID file that is
689- # understood by the Launchpad services framework.
690- global service_name
691- make_pidfile(service_name)
692-
693- host, port = get_service_endpoint()
694- server = HTTPServer((host, port), GoogleRequestHandler)
695-
696- log.info("Starting HTTP Google webservice server on port %s", port)
697- server.serve_forever()
698
699=== modified file 'lib/lp/services/sitesearch/interfaces.py'
700--- lib/lp/services/sitesearch/interfaces.py 2018-04-03 05:44:57 +0000
701+++ lib/lp/services/sitesearch/interfaces.py 2018-05-21 21:36:59 +0000
702@@ -9,7 +9,6 @@
703 'ISearchResult',
704 'ISearchResults',
705 'ISearchService',
706- 'GoogleWrongGSPVersion',
707 'SiteSearchResponseError',
708 'active_search_service',
709 ]
710@@ -80,10 +79,6 @@
711 """Iterate over the items in the collection."""
712
713
714-class GoogleWrongGSPVersion(ValueError):
715- """Raised when the content is not parsable Google Search Protocol XML."""
716-
717-
718 class SiteSearchResponseError(ValueError):
719 """Raised when the search engine's response cannot be parsed."""
720
721
722=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml'
723--- lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml 2009-08-13 15:12:16 +0000
724+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-1.xml 1970-01-01 00:00:00 +0000
725@@ -1,63 +0,0 @@
726-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
727-<GSP VER="3.2">
728-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
729-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
730-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
731-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
732-<PARAM name="ie" value="utf8" original_value="utf8"/>
733-<PARAM name="num" value="20" original_value="20"/>
734-<PARAM name="oe" value="utf8" original_value="utf8"/>
735-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
736-<PARAM name="q" value="bugs" original_value="bugs"/>
737-<PARAM name="start" value="0" original_value="0"/>
738-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
739-<PARAM name="hl" value="en" original_value="en"/>
740-<Context><title>Launchpad Search Engine</title></Context><RES SN="1" EN="20">
741-
742-<M>25</M>
743-<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>
744-</NB>
745-
746-<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>
747-
748-<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>
749-
750-<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>
751-
752-<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>
753-
754-<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>
755-
756-<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>
757-
758-<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>
759-
760-<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>
761-
762-<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>
763-
764-<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>
765-
766-<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>
767-
768-<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>
769-
770-<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>
771-
772-<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>
773-
774-<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>
775-
776-<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>
777-
778-<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>
779-
780-<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>
781-
782-<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>
783-
784-<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>
785-
786-</RES>
787-</GSP>
788-
789
790=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml'
791--- lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml 2008-05-23 20:06:17 +0000
792+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-bugs-2.xml 1970-01-01 00:00:00 +0000
793@@ -1,33 +0,0 @@
794-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
795-<GSP VER="3.2">
796-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
797-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
798-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
799-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
800-<PARAM name="ie" value="utf8" original_value="utf8"/>
801-<PARAM name="num" value="20" original_value="20"/>
802-<PARAM name="oe" value="utf8" original_value="utf8"/>
803-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
804-<PARAM name="q" value="bugs" original_value="bugs"/>
805-<PARAM name="start" value="20" original_value="20"/>
806-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
807-<PARAM name="hl" value="en" original_value="en"/>
808-<Context><title>Launchpad Search Engine</title></Context><RES SN="21" EN="25">
809-
810-<M>25</M>
811-<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>
812-</NB>
813-
814-<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>
815-
816-<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>
817-
818-<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>
819-
820-<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>
821-
822-<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>
823-
824-</RES>
825-</GSP>
826-
827
828=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml'
829--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml 2008-05-15 21:58:33 +0000
830+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-matches.xml 1970-01-01 00:00:00 +0000
831@@ -1,36 +0,0 @@
832-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
833-<GSP VER="3.2">
834-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
835-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
836-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
837-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
838-<PARAM name="ie" value="utf8" original_value="utf8"/>
839-<PARAM name="num" value="20" original_value="20"/>
840-<PARAM name="oe" value="utf8" original_value="utf8"/>
841-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
842-<PARAM name="q" value="bugs" original_value="bugs"/>
843-<PARAM name="start" value="0" original_value="0"/>
844-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
845-<PARAM name="hl" value="en" original_value="en"/>
846-<Context><title>Launchpad Search Engine</title></Context>
847-
848-<RES SN="1" EN="1">
849-<M>~1</M>
850-<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>
851-</NB>
852-
853-<R N="1">
854- <U>https://bugs.launchpad.net/</U>
855- <UE>https://bugs.launchpad.net/</UE>
856- <T>Launchpad Bugs</T>
857- <RK>0</RK>
858- <CRAWLDATE>17 hours ago</CRAWLDATE>
859- <S>This 'R'esult is fine, but the 'M' element above is not an int.</S>
860- <LANG>en</LANG>
861- <Label>_cse_ixpjdn21yfg</Label>
862- <HAS><L/><RT/></HAS>
863-</R>
864-
865-</RES>
866-</GSP>
867-
868
869=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml'
870--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml 2008-05-15 21:58:33 +0000
871+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-param.xml 1970-01-01 00:00:00 +0000
872@@ -1,18 +0,0 @@
873-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
874-<GSP VER="3.2">
875-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
876-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
877-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
878-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
879-<PARAM name="ie" value="utf8" original_value="utf8"/>
880-<PARAM name="num" value="20" original_value="20"/>
881-<PARAM name="oe" value="utf8" original_value="utf8"/>
882-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
883-<PARAM name="q" value="bugs" original_value="bugs"/>
884-<PARAM name="start" value="" original_value="0"/>
885-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
886-<PARAM name="hl" value="en" original_value="en"/>
887-<Context><title>Launchpad Search Engine</title></Context>
888-
889-</GSP>
890-
891
892=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml'
893--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml 2008-12-05 19:41:05 +0000
894+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incompatible-result.xml 1970-01-01 00:00:00 +0000
895@@ -1,36 +0,0 @@
896-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
897-<GSP VER="3.3">
898-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
899-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
900-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
901-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
902-<PARAM name="ie" value="utf8" original_value="utf8"/>
903-<PARAM name="num" value="20" original_value="20"/>
904-<PARAM name="oe" value="utf8" original_value="utf8"/>
905-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
906-<PARAM name="q" value="bugs" original_value="bugs"/>
907-<PARAM name="start" value="0" original_value="0"/>
908-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
909-<PARAM name="hl" value="en" original_value="en"/>
910-<Context><title>Launchpad Search Engine</title></Context>
911-
912-<RES SN="1" EN="1">
913-<M>1000</M>
914-<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>
915-</NB>
916-
917-<RESULT N="1">
918- <url>https://bugs.launchpad.net/</url>
919- <UE>https://bugs.launchpad.net/</UE>
920- <T>Launchpad Bugs</T>
921- <RK>0</RK>
922- <CRAWLDATE>17 hours ago</CRAWLDATE>
923- <S>This 'R'esult is missing a 'U' element, it has a 'url' instead.</S>
924- <LANG>en</LANG>
925- <Label>_cse_ixpjdn21yfg</Label>
926- <HAS><L/><RT/></HAS>
927-</RESULT>
928-
929-</RES>
930-</GSP>
931-
932
933=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml'
934--- lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml 2008-12-05 16:02:02 +0000
935+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-incomplete-response.xml 1970-01-01 00:00:00 +0000
936@@ -1,1 +0,0 @@
937-
938
939=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt'
940--- lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt 2018-03-16 14:02:16 +0000
941+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-mapping.txt 1970-01-01 00:00:00 +0000
942@@ -1,24 +0,0 @@
943-# This file defines a mapping of Google search service URLs to the XML
944-# files that should be returned by them.
945-#
946-# The format is 'url XMLfile'. Blank lines and lines starting with '#'
947-# are ignored.
948-#
949-# The special URL, '*', is returned for all un-mapped URLs.
950-
951-* googlesearchservice-no-results.xml
952-
953-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=bug&start=0 googlesearchservice-bugs-1.xml
954-
955-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=bug&start=20 googlesearchservice-bugs-2.xml
956-
957-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=launchpad&start=0 googlesearchservice-bugs-1.xml
958-
959-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=launchpad&start=20 googlesearchservice-bugs-2.xml
960-
961-/cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=gnomebaker&start=0 googlesearchservice-incomplete-response.xml
962-
963-/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
964-
965-# This stub service is also used to impersonate the Blog feed
966-/blog-feed blog.launchpad.net-feed.xml
967
968=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml'
969--- lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml 2008-05-29 21:40:39 +0000
970+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-summary.xml 1970-01-01 00:00:00 +0000
971@@ -1,58 +0,0 @@
972-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
973-<GSP VER="3.2">
974-<TM>0.574436</TM>
975-<Q>edge site:launchpad.net</Q>
976-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
977-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
978-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
979-<PARAM name="ie" value="utf8" original_value="utf8"/>
980-<PARAM name="num" value="20" original_value="20"/>
981-<PARAM name="oe" value="utf8" original_value="utf8"/>
982-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
983-<PARAM name="q" value="edge" original_value="gobuntu"/>
984-<PARAM name="start" value="0" original_value="0"/>
985-<PARAM name="adkw" value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI" original_value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI"/>
986-<PARAM name="hl" value="en" original_value="en"/>
987-<Context>
988-<title>Launchpad Search Engine</title>
989-</Context>
990-<RES SN="1" EN="2">
991-
992-<M>2</M>
993-<FI/>
994-<NB>
995-<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>
996-</NB>
997-
998-<R N="1">
999-<U>https://blueprints.edge.launchpad.net/ubuntu/+spec/gobuntu-hardy</U>
1000-<UE>https://blueprints.edge.launchpad.net/ubuntu/%2Bspec/gobuntu-hardy</UE>
1001-<T>Blueprint: &lt;b&gt;gobuntu&lt;/b&gt; hardy</T>
1002-<RK>0</RK>
1003-<S></S>
1004-<LANG>en</LANG>
1005-<Label>_cse_ixpjdn21yfg</Label>
1006-<HAS>
1007-<L/>
1008-<RT/>
1009-</HAS>
1010-</R>
1011-
1012-<R N="2">
1013-<U>https://blueprints.launchpad.net/ubuntu/+spec/gobuntu-hardy</U>
1014-<UE>https://blueprints.launchpad.net/ubuntu/%2Bspec/gobuntu-hardy</UE>
1015-<T>Blueprint: &lt;b&gt;Gobuntu&lt;/b&gt; 8.04</T>
1016-<RK>0</RK>
1017-<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>
1018-<LANG>en</LANG>
1019-<Label>_cse_ixpjdn21yfg</Label>
1020-<HAS>
1021-<L/>
1022-<C SZ="17k" CID="3PPx0kdgdSsJ"/>
1023-<RT/>
1024-</HAS>
1025-</R>
1026-
1027-</RES>
1028-</GSP>
1029-
1030
1031=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml'
1032--- lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml 2010-10-24 21:00:11 +0000
1033+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-title.xml 1970-01-01 00:00:00 +0000
1034@@ -1,58 +0,0 @@
1035-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1036-<GSP VER="3.2">
1037-<TM>0.574436</TM>
1038-<Q>edge site:launchpad.net</Q>
1039-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
1040-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
1041-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
1042-<PARAM name="ie" value="utf8" original_value="utf8"/>
1043-<PARAM name="num" value="20" original_value="20"/>
1044-<PARAM name="oe" value="utf8" original_value="utf8"/>
1045-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
1046-<PARAM name="q" value="edge" original_value="edge"/>
1047-<PARAM name="start" value="0" original_value="0"/>
1048-<PARAM name="adkw" value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI" original_value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI"/>
1049-<PARAM name="hl" value="en" original_value="en"/>
1050-<Context>
1051-<title>Launchpad Search Engine</title>
1052-</Context>
1053-<RES SN="1" EN="2">
1054-
1055-<M>2</M>
1056-<FI/>
1057-<NB>
1058-<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>
1059-</NB>
1060-
1061-<R N="1">
1062-<U>https://launchpad.net/gc</U>
1063-<UE>https://launchpad.net/gc</UE>
1064-<RK>0</RK>
1065-<S>
1066-</S>
1067-<LANG>en</LANG>
1068-<Label>_cse_ixpjdn21yfg</Label>
1069-<HAS>
1070-<L/>
1071-<RT/>
1072-</HAS>
1073-</R>
1074-
1075-<R N="2">
1076-<U>https://bugs.launchpad.net/bugs/205991</U>
1077-<UE>https://bugs.launchpad.net/bugs/205991</UE>
1078-<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>
1079-<RK>0</RK>
1080-<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>
1081-<LANG>en</LANG>
1082-<Label>_cse_ixpjdn21yfg</Label>
1083-<HAS>
1084-<L/>
1085-<C SZ="28k" CID="iuKmxfKzs1UJ"/>
1086-<RT/>
1087-</HAS>
1088-</R>
1089-
1090-</RES>
1091-</GSP>
1092-
1093
1094=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml'
1095--- lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml 2008-05-29 21:40:39 +0000
1096+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-missing-url.xml 1970-01-01 00:00:00 +0000
1097@@ -1,57 +0,0 @@
1098-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1099-<GSP VER="3.2">
1100-<TM>0.574436</TM>
1101-<Q>edge site:launchpad.net</Q>
1102-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
1103-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
1104-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
1105-<PARAM name="ie" value="utf8" original_value="utf8"/>
1106-<PARAM name="num" value="20" original_value="20"/>
1107-<PARAM name="oe" value="utf8" original_value="utf8"/>
1108-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
1109-<PARAM name="q" value="edge" original_value="gobuntu"/>
1110-<PARAM name="start" value="0" original_value="0"/>
1111-<PARAM name="adkw" value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI" original_value="AELymgVSAg4Z0EIH2LyxeADeNPeaFHoipa7pZ_GD5K757xvLNb3T2vK__0jEvkeBwqMHVUHFWegTVcYpBPvbZwEp5kHEls6J5_vB52dDHCO-cBo5GcKKzLI"/>
1112-<PARAM name="hl" value="en" original_value="en"/>
1113-<Context>
1114-<title>Launchpad Search Engine</title>
1115-</Context>
1116-<RES SN="1" EN="2">
1117-
1118-<M>2</M>
1119-<FI/>
1120-<NB>
1121-<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>
1122-</NB>
1123-
1124-<R N="1">
1125-<!-- Non public URL -->
1126-<T>Blueprint: &lt;b&gt;gobuntu&lt;/b&gt; hardy</T>
1127-<RK>0</RK>
1128-<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>
1129-<LANG>en</LANG>
1130-<Label>_cse_ixpjdn21yfg</Label>
1131-<HAS>
1132-<L/>
1133-<RT/>
1134-</HAS>
1135-</R>
1136-
1137-<R N="2">
1138-<U>https://blueprints.launchpad.net/ubuntu/+spec/gobuntu-hardy</U>
1139-<UE>https://blueprints.launchpad.net/ubuntu/%2Bspec/gobuntu-hardy</UE>
1140-<T>Blueprint: &lt;b&gt;Gobuntu&lt;/b&gt; 8.04</T>
1141-<RK>0</RK>
1142-<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>
1143-<LANG>en</LANG>
1144-<Label>_cse_ixpjdn21yfg</Label>
1145-<HAS>
1146-<L/>
1147-<C SZ="17k" CID="3PPx0kdgdSsJ"/>
1148-<RT/>
1149-</HAS>
1150-</R>
1151-
1152-</RES>
1153-</GSP>
1154-
1155
1156=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml'
1157--- lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml 2010-12-01 19:30:04 +0000
1158+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-negative-total.xml 1970-01-01 00:00:00 +0000
1159@@ -1,35 +0,0 @@
1160-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1161-<GSP VER="3.3">
1162-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
1163-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
1164-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
1165-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
1166-<PARAM name="ie" value="utf8" original_value="utf8"/>
1167-<PARAM name="num" value="20" original_value="20"/>
1168-<PARAM name="oe" value="utf8" original_value="utf8"/>
1169-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
1170-<PARAM name="q" value="bugs" original_value="bugs"/>
1171-<PARAM name="start" value="0" original_value="0"/>
1172-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
1173-<PARAM name="hl" value="en" original_value="en"/>
1174-<Context><title>Launchpad Search Engine</title></Context>
1175-
1176-<RES SN="1" EN="1">
1177-<M>-1</M>
1178-<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>
1179-</NB>
1180-
1181-<R N="1">
1182- <U>https://bugs.launchpad.net/</U>
1183- <UE>https://bugs.launchpad.net/</UE>
1184- <T>A Title</T>
1185- <RK>0</RK>
1186- <CRAWLDATE>17 hours ago</CRAWLDATE>
1187- <S>A 'R'esult.</S>
1188- <LANG>en</LANG>
1189- <Label>_cse_ixpjdn21yfg</Label>
1190- <HAS><L/><RT/></HAS>
1191-</R>
1192-
1193-</RES>
1194-</GSP>
1195
1196=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml'
1197--- lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml 2008-12-05 19:41:05 +0000
1198+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-no-meaningful-results.xml 1970-01-01 00:00:00 +0000
1199@@ -1,35 +0,0 @@
1200-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1201-<GSP VER="3.3">
1202-<TM>0.416786</TM><Q>no-meaning site:launchpad.net</Q>
1203-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
1204-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
1205-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
1206-<PARAM name="ie" value="utf8" original_value="utf8"/>
1207-<PARAM name="num" value="20" original_value="20"/>
1208-<PARAM name="oe" value="utf8" original_value="utf8"/>
1209-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
1210-<PARAM name="q" value="no-meaning" original_value="no-meaning"/>
1211-<PARAM name="start" value="0" original_value="0"/>
1212-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
1213-<PARAM name="hl" value="en" original_value="en"/>
1214-<Context><title>Launchpad Search Engine</title></Context>
1215-
1216-<RES SN="1" EN="1">
1217-<M>1</M>
1218-<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>
1219-</NB>
1220-
1221-<R N="1">
1222- <U>https://bugs.launchpad.net/</U>
1223- <UE>https://bugs.launchpad.net/</UE>
1224- <T></T>
1225- <RK>0</RK>
1226- <CRAWLDATE>17 hours ago</CRAWLDATE>
1227- <S>This 'R'esult does not have a title.</S>
1228- <LANG>en</LANG>
1229- <Label>_cse_ixpjdn21yfg</Label>
1230- <HAS><L/><RT/></HAS>
1231-</R>
1232-
1233-</RES>
1234-</GSP>
1235
1236=== removed file 'lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml'
1237--- lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml 2008-05-15 21:58:33 +0000
1238+++ lib/lp/services/sitesearch/tests/data/googlesearchservice-no-results.xml 1970-01-01 00:00:00 +0000
1239@@ -1,17 +0,0 @@
1240-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1241-<GSP VER="3.2">
1242-<TM>0.416786</TM><Q>bugs site:launchpad.net</Q>
1243-<PARAM name="as_sitesearch" value="launchpad.net" original_value="launchpad.net"/>
1244-<PARAM name="client" value="google-csbe" original_value="google-csbe"/>
1245-<PARAM name="cx" value="011948274177882366108:ixpjdn21yfg" original_value="011948274177882366108%3Aixpjdn21yfg"/>
1246-<PARAM name="ie" value="utf8" original_value="utf8"/>
1247-<PARAM name="num" value="20" original_value="20"/>
1248-<PARAM name="oe" value="utf8" original_value="utf8"/>
1249-<PARAM name="output" value="xml_no_dtd" original_value="xml_no_dtd"/>
1250-<PARAM name="q" value="bugs" original_value="bugs"/>
1251-<PARAM name="start" value="0" original_value="0"/>
1252-<PARAM name="adkw" value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ" original_value="AELymgURIr4plE6V5qUaesxj1S8kUSFxCVrVLNU_OeCogh9Q7W5be6lEGMcbb0q6WTDgLL7zsnlnYGLvVrsdxgx3AamFm0M6ARaxerSLvSf-1JQHrOLuhsQ"/>
1253-<PARAM name="hl" value="en" original_value="en"/>
1254-<Context><title>Launchpad Search Engine</title></Context>
1255-</GSP>
1256-
1257
1258=== removed file 'lib/lp/services/sitesearch/tests/googleserviceharness.py'
1259--- lib/lp/services/sitesearch/tests/googleserviceharness.py 2018-03-28 17:00:10 +0000
1260+++ lib/lp/services/sitesearch/tests/googleserviceharness.py 1970-01-01 00:00:00 +0000
1261@@ -1,107 +0,0 @@
1262-# Copyright 2009 Canonical Ltd. This software is licensed under the
1263-# GNU Affero General Public License version 3 (see the file LICENSE).
1264-
1265-"""
1266-Fixtures for running the Google test webservice.
1267-"""
1268-
1269-__metaclass__ = type
1270-
1271-__all__ = ['GoogleServiceTestSetup']
1272-
1273-
1274-import errno
1275-import os
1276-import signal
1277-
1278-from lp.services.sitesearch import googletestservice
1279-
1280-
1281-class GoogleServiceTestSetup:
1282- """Set up the Google web service stub for use in functional tests.
1283- """
1284-
1285- # XXX gary 2008-12-06 bug=305858: Spurious test failures discovered on
1286- # buildbot, builds 40 and 43. The locations of the failures are marked
1287- # below with " # SPURIOUS FAILURE". To reinstate, add the text below back
1288- # to the docstring above. Note that the test that uses this setup,
1289- # google-service-stub.txt, is also disabled. See test_doc.py.
1290- """
1291- >>> from lp.services.sitesearch.googletestservice import (
1292- ... service_is_available)
1293- >>> from lp.services.config import config
1294-
1295- >>> assert not service_is_available() # Sanity check. # SPURIOUS FAILURE
1296-
1297- >>> GoogleServiceTestSetup().setUp()
1298-
1299- After setUp is called, a Google test service instance is running.
1300-
1301- >>> assert service_is_available()
1302- >>> assert GoogleServiceTestSetup.service is not None
1303-
1304- After tearDown is called, the service is shut down.
1305-
1306- >>> GoogleServiceTestSetup().tearDown()
1307-
1308- >>> assert not service_is_available()
1309- >>> assert GoogleServiceTestSetup.service is None
1310-
1311- The fixture can be started and stopped multiple time in succession:
1312-
1313- >>> GoogleServiceTestSetup().setUp()
1314- >>> assert service_is_available()
1315-
1316- Having a service instance already running doesn't prevent a new
1317- service from starting. The old instance is killed off and replaced
1318- by the new one.
1319-
1320- >>> old_pid = GoogleServiceTestSetup.service.pid
1321- >>> GoogleServiceTestSetup().setUp() # SPURIOUS FAILURE
1322- >>> GoogleServiceTestSetup.service.pid != old_pid
1323- True
1324-
1325- Tidy up.
1326-
1327- >>> GoogleServiceTestSetup().tearDown()
1328- >>> assert not service_is_available()
1329-
1330- """
1331-
1332- service = None # A reference to our running service.
1333-
1334- def setUp(self):
1335- self.startService()
1336-
1337- def tearDown(self):
1338- self.stopService()
1339-
1340- @classmethod
1341- def startService(cls):
1342- """Start the webservice."""
1343- googletestservice.kill_running_process()
1344- cls.service = googletestservice.start_as_process()
1345- assert cls.service, "The Search service process did not start."
1346- try:
1347- googletestservice.wait_for_service()
1348- except RuntimeError:
1349- # The service didn't start itself soon enough. We must
1350- # make sure to kill any errant processes that may be
1351- # hanging around.
1352- cls.stopService()
1353- raise
1354-
1355- @classmethod
1356- def stopService(cls):
1357- """Shut down the webservice instance."""
1358- if cls.service:
1359- try:
1360- os.kill(cls.service.pid, signal.SIGTERM)
1361- except OSError as error:
1362- if error.errno != errno.ESRCH:
1363- raise
1364- # The process with the given pid doesn't exist, so there's
1365- # nothing to kill or wait for.
1366- else:
1367- cls.service.wait()
1368- cls.service = None
1369
1370=== removed file 'lib/lp/services/sitesearch/tests/test_google.py'
1371--- lib/lp/services/sitesearch/tests/test_google.py 2018-04-16 18:43:52 +0000
1372+++ lib/lp/services/sitesearch/tests/test_google.py 1970-01-01 00:00:00 +0000
1373@@ -1,304 +0,0 @@
1374-# Copyright 2011-2016 Canonical Ltd. This software is licensed under the
1375-# GNU Affero General Public License version 3 (see the file LICENSE).
1376-
1377-"""Test the google search service."""
1378-
1379-from __future__ import absolute_import, print_function, unicode_literals
1380-
1381-__metaclass__ = type
1382-
1383-import os.path
1384-
1385-from fixtures import MockPatch
1386-from requests.exceptions import (
1387- ConnectionError,
1388- HTTPError,
1389- )
1390-from testtools.matchers import (
1391- HasLength,
1392- MatchesListwise,
1393- MatchesStructure,
1394- )
1395-
1396-from lp.services.config import config
1397-from lp.services.sitesearch import GoogleSearchService
1398-from lp.services.sitesearch.interfaces import (
1399- GoogleWrongGSPVersion,
1400- SiteSearchResponseError,
1401- )
1402-from lp.services.timeout import TimeoutError
1403-from lp.testing import TestCase
1404-from lp.testing.layers import GoogleLaunchpadFunctionalLayer
1405-
1406-
1407-class TestGoogleSearchService(TestCase):
1408- """Test GoogleSearchService."""
1409-
1410- layer = GoogleLaunchpadFunctionalLayer
1411-
1412- def setUp(self):
1413- super(TestGoogleSearchService, self).setUp()
1414- self.search_service = GoogleSearchService()
1415- self.base_path = os.path.normpath(
1416- os.path.join(os.path.dirname(__file__), 'data'))
1417-
1418- def test_configuration(self):
1419- self.assertEqual(config.google.site, self.search_service.site)
1420- self.assertEqual(
1421- config.google.client_id, self.search_service.client_id)
1422-
1423- def test_create_search_url(self):
1424- self.assertEndsWith(
1425- self.search_service.create_search_url(terms='svg +bugs'),
1426- '&q=svg+%2Bbugs&start=0')
1427-
1428- def test_create_search_url_escapes_unicode_chars(self):
1429- self.assertEndsWith(
1430- self.search_service.create_search_url(
1431- 'Carlos Perell\xf3 Mar\xedn'),
1432- '&q=Carlos+Perell%C3%B3+Mar%C3%ADn&start=0')
1433-
1434- def test_create_search_url_with_offset(self):
1435- self.assertEndsWith(
1436- self.search_service.create_search_url(terms='svg +bugs', start=20),
1437- '&q=svg+%2Bbugs&start=20')
1438-
1439- def test_create_search_url_empty_terms(self):
1440- self.assertRaisesWithContent(
1441- ValueError, "Missing value for parameter 'q'.",
1442- self.search_service.create_search_url, '')
1443-
1444- def test_create_search_url_null_terms(self):
1445- self.assertRaisesWithContent(
1446- ValueError, "Missing value for parameter 'q'.",
1447- self.search_service.create_search_url, None)
1448-
1449- def test_create_search_url_requires_start(self):
1450- self.assertRaisesWithContent(
1451- ValueError, "Value for parameter 'start' is not an int.",
1452- self.search_service.create_search_url, 'bugs', 'true')
1453-
1454- def test_parse_search_response_incompatible_param(self):
1455- """The PageMatches's start attribute comes from the GSP XML element
1456- '<PARAM name="start" value="0" original_value="0"/>'. When it cannot
1457- be found and the value cast to an int, an error is raised. There is
1458- nothing in the value attribute in the next test, so an error is raised.
1459- """
1460- file_name = os.path.join(
1461- self.base_path, 'googlesearchservice-incompatible-param.xml')
1462- with open(file_name, 'r') as response_file:
1463- response = response_file.read()
1464- self.assertNotIn('<M>', response)
1465-
1466- self.assertRaisesWithContent(
1467- GoogleWrongGSPVersion,
1468- "Could not get the 'start' from the GSP XML response.",
1469- self.search_service._parse_search_response, response)
1470-
1471- def test_parse_search_response_invalid_total(self):
1472- """The PageMatches's total attribute comes from the GSP XML element
1473- '<M>5</M>'. When it cannot be found and the value cast to an int,
1474- an error is raised. If Google were to redefine the meaning of the M
1475- element to use a '~' to indicate an approximate total, an error would
1476- be raised.
1477- """
1478- file_name = os.path.join(
1479- self.base_path, 'googlesearchservice-incompatible-matches.xml')
1480- with open(file_name, 'r') as response_file:
1481- response = response_file.read()
1482- self.assertIn('<M>~1</M>', response)
1483-
1484- self.assertRaisesWithContent(
1485- GoogleWrongGSPVersion,
1486- "Could not get the 'total' from the GSP XML response.",
1487- self.search_service._parse_search_response, response)
1488-
1489- def test_parse_search_response_negative_total(self):
1490- """If the total is ever less than zero (see bug 683115),
1491- this is expected: we simply return a total of 0.
1492- """
1493- file_name = os.path.join(
1494- self.base_path, 'googlesearchservice-negative-total.xml')
1495- with open(file_name, 'r') as response_file:
1496- response = response_file.read()
1497- self.assertIn('<M>-1</M>', response)
1498-
1499- matches = self.search_service._parse_search_response(response)
1500- self.assertEqual(0, matches.total)
1501-
1502- def test_parse_search_response_missing_title(self):
1503- """A PageMatch requires a title, url, and a summary. If those elements
1504- ('<T>', '<U>', '<S>') cannot be found nested in an '<R>' a PageMatch
1505- cannot be made. A missing title (<T>) indicates a bad page on Launchpad
1506- so it is ignored. In this example, The first match is missing a title,
1507- so only the second page is present in the PageMatches.
1508- """
1509- file_name = os.path.join(
1510- self.base_path, 'googlesearchservice-missing-title.xml')
1511- with open(file_name, 'r') as response_file:
1512- response = response_file.read()
1513-
1514- matches = self.search_service._parse_search_response(response)
1515- self.assertThat(matches, MatchesListwise([
1516- MatchesStructure.byEquality(
1517- title=(
1518- u'Bug #205991 in Ubuntu: \u201cCan&#39;t pair '
1519- u'Bluetooth Logitech DiNovo <b>Edge</b> <b>...</b>'),
1520- url='http://bugs.launchpad.dev/bugs/205991'),
1521- ]))
1522-
1523- def test_parse_search_response_missing_summary(self):
1524- """When a match is missing a summary (<S>), it is skipped because
1525- there is no information about why it matched. This appears to relate to
1526- pages that are in the index, but should be removed. In this example
1527- taken from real data, the links are to the same page on different
1528- vhosts. The edge vhost has no summary, so it is skipped.
1529- """
1530- file_name = os.path.join(
1531- self.base_path, 'googlesearchservice-missing-summary.xml')
1532- with open(file_name, 'r') as response_file:
1533- response = response_file.read()
1534-
1535- matches = self.search_service._parse_search_response(response)
1536- self.assertThat(matches, MatchesListwise([
1537- MatchesStructure.byEquality(
1538- title='Blueprint: <b>Gobuntu</b> 8.04',
1539- url=(
1540- 'http://blueprints.launchpad.dev'
1541- '/ubuntu/+spec/gobuntu-hardy')),
1542- ]))
1543-
1544- def test_parse_search_response_missing_url(self):
1545- """When the URL (<U>) cannot be found the match is skipped. There are
1546- no examples of this. We do not want this hypothetical situation to give
1547- users a bad experience.
1548- """
1549- file_name = os.path.join(
1550- self.base_path, 'googlesearchservice-missing-url.xml')
1551- with open(file_name, 'r') as response_file:
1552- response = response_file.read()
1553-
1554- matches = self.search_service._parse_search_response(response)
1555- self.assertThat(matches, MatchesListwise([
1556- MatchesStructure.byEquality(
1557- title='Blueprint: <b>Gobuntu</b> 8.04',
1558- url=(
1559- 'http://blueprints.launchpad.dev'
1560- '/ubuntu/+spec/gobuntu-hardy')),
1561- ]))
1562-
1563- def test_parse_search_response_with_no_meaningful_results(self):
1564- """If no matches are found in the response, and there are 20 or fewer
1565- results, an Empty PageMatches is returned. This happens when the
1566- results are missing titles and summaries. This is not considered to be
1567- a problem because the small number implies that Google did a poor job
1568- of indexing pages or indexed the wrong Launchpad server. In this
1569- example, there is only one match, but the results is missing a title so
1570- there is not enough information to make a PageMatch.
1571- """
1572- file_name = os.path.join(
1573- self.base_path, 'googlesearchservice-no-meaningful-results.xml')
1574- with open(file_name, 'r') as response_file:
1575- response = response_file.read()
1576- self.assertIn('<M>1</M>', response)
1577-
1578- matches = self.search_service._parse_search_response(response)
1579- self.assertThat(matches, HasLength(0))
1580-
1581- def test_parse_search_response_with_incompatible_result(self):
1582- """If no matches are found in the response, and there are more than 20
1583- possible matches, an error is raised. Unlike the previous example there
1584- are lots of results; there is a possibility that the GSP version is
1585- incompatible. This example says it has 1000 matches, but none of the R
1586- tags can be parsed (because the markup was changed to use RESULT).
1587- """
1588- file_name = os.path.join(
1589- self.base_path, 'googlesearchservice-incompatible-result.xml')
1590- with open(file_name, 'r') as response_file:
1591- response = response_file.read()
1592- self.assertIn('<M>1000</M>', response)
1593-
1594- self.assertRaisesWithContent(
1595- GoogleWrongGSPVersion,
1596- "Could not get any PageMatches from the GSP XML response.",
1597- self.search_service._parse_search_response, response)
1598-
1599- def test_search_converts_HTTPError(self):
1600- # The method converts HTTPError to SiteSearchResponseError.
1601- args = ('url', 500, 'oops', {}, None)
1602- self.useFixture(MockPatch(
1603- 'lp.services.sitesearch.urlfetch', side_effect=HTTPError(*args)))
1604- self.assertRaises(
1605- SiteSearchResponseError, self.search_service.search, 'fnord')
1606-
1607- def test_search_converts_ConnectionError(self):
1608- # The method converts ConnectionError to SiteSearchResponseError.
1609- self.useFixture(MockPatch(
1610- 'lp.services.sitesearch.urlfetch',
1611- side_effect=ConnectionError('oops')))
1612- self.assertRaises(
1613- SiteSearchResponseError, self.search_service.search, 'fnord')
1614-
1615- def test_search_converts_TimeoutError(self):
1616- # The method converts TimeoutError to SiteSearchResponseError.
1617- self.useFixture(MockPatch(
1618- 'lp.services.sitesearch.urlfetch',
1619- side_effect=TimeoutError('oops')))
1620- self.assertRaises(
1621- SiteSearchResponseError, self.search_service.search, 'fnord')
1622-
1623- def test_parse_search_response_SyntaxError(self):
1624- # The method converts SyntaxError to SiteSearchResponseError.
1625- self.useFixture(MockPatch(
1626- 'lp.services.sitesearch.urlfetch',
1627- side_effect=SyntaxError('oops')))
1628- self.assertRaises(
1629- SiteSearchResponseError,
1630- self.search_service._parse_search_response, '')
1631-
1632- def test_parse_search_response_IndexError(self):
1633- # The method converts IndexError to SiteSearchResponseError.
1634- self.useFixture(MockPatch(
1635- 'lp.services.sitesearch.urlfetch', side_effect=IndexError('oops')))
1636- data = (
1637- '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
1638- '<GSP VER="3.2"></GSP>')
1639- self.assertRaises(
1640- SiteSearchResponseError,
1641- self.search_service._parse_search_response, data)
1642-
1643- def test_search_with_results(self):
1644- matches = self.search_service.search('bug')
1645- self.assertEqual(0, matches.start)
1646- self.assertEqual(25, matches.total)
1647- self.assertEqual(20, len(matches))
1648-
1649- def test_search_with_results_and_offset(self):
1650- matches = self.search_service.search('bug', start=20)
1651- self.assertEqual(20, matches.start)
1652- self.assertEqual(25, matches.total)
1653- self.assertEqual(5, len(matches))
1654- self.assertEqual([
1655- 'http://bugs.launchpad.dev/ubuntu/hoary/+bug/2',
1656- 'http://bugs.launchpad.dev/debian/+source/mozilla-firefox/+bug/2',
1657- 'http://bugs.launchpad.dev/debian/+source/mozilla-firefox/+bug/3',
1658- 'http://bugs.launchpad.dev/bugs/bugtrackers',
1659- 'http://bugs.launchpad.dev/bugs/bugtrackers/debbugs'],
1660- [match.url for match in matches])
1661-
1662- def test_search_no_results(self):
1663- matches = self.search_service.search('fnord')
1664- self.assertEqual(0, matches.start)
1665- self.assertEqual(0, matches.total)
1666- self.assertEqual(0, len(matches))
1667-
1668- def test_search_no_meaningful_results(self):
1669- matches = self.search_service.search('no-meaningful')
1670- self.assertEqual(0, matches.start)
1671- self.assertEqual(1, matches.total)
1672- self.assertEqual(0, len(matches))
1673-
1674- def test_search_incomplete_response(self):
1675- self.assertRaises(
1676- SiteSearchResponseError,
1677- self.search_service.search, 'gnomebaker')
1678
1679=== removed file 'lib/lp/services/sitesearch/tests/test_googleharness.py'
1680--- lib/lp/services/sitesearch/tests/test_googleharness.py 2018-03-16 14:02:16 +0000
1681+++ lib/lp/services/sitesearch/tests/test_googleharness.py 1970-01-01 00:00:00 +0000
1682@@ -1,10 +0,0 @@
1683-# Copyright 2009 Canonical Ltd. This software is licensed under the
1684-# GNU Affero General Public License version 3 (see the file LICENSE).
1685-
1686-import doctest
1687-
1688-
1689-def test_suite():
1690- return doctest.DocTestSuite(
1691- 'lp.services.sitesearch.tests.googleserviceharness',
1692- optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS)
1693
1694=== modified file 'lib/lp/services/sitesearch/tests/test_testservices.py'
1695--- lib/lp/services/sitesearch/tests/test_testservices.py 2018-04-13 20:26:48 +0000
1696+++ lib/lp/services/sitesearch/tests/test_testservices.py 2018-05-21 21:36:59 +0000
1697@@ -15,10 +15,7 @@
1698
1699 from lp.services.osutils import process_exists
1700 from lp.services.pidfile import pidfile_path
1701-from lp.services.sitesearch import (
1702- bingtestservice,
1703- googletestservice,
1704- )
1705+from lp.services.sitesearch import bingtestservice
1706
1707
1708 class TestServiceUtilities(WithScenarios, unittest.TestCase):
1709@@ -28,9 +25,6 @@
1710 ("Bing", {
1711 "testservice": bingtestservice,
1712 }),
1713- ("Google", {
1714- "testservice": googletestservice,
1715- }),
1716 ]
1717
1718 def test_stale_pid_file_cleanup(self):
1719
1720=== modified file 'lib/lp/testing/layers.py'
1721--- lib/lp/testing/layers.py 2018-03-27 20:45:52 +0000
1722+++ lib/lp/testing/layers.py 2018-05-21 21:36:59 +0000
1723@@ -28,8 +28,6 @@
1724 'DatabaseFunctionalLayer',
1725 'DatabaseLayer',
1726 'FunctionalLayer',
1727- 'GoogleLaunchpadFunctionalLayer',
1728- 'GoogleServiceLayer',
1729 'LaunchpadFunctionalLayer',
1730 'LaunchpadLayer',
1731 'LaunchpadScriptLayer',
1732@@ -131,9 +129,6 @@
1733 from lp.services.sitesearch.tests.bingserviceharness import (
1734 BingServiceTestSetup,
1735 )
1736-from lp.services.sitesearch.tests.googleserviceharness import (
1737- GoogleServiceTestSetup,
1738- )
1739 from lp.services.testing.profiled import profiled
1740 from lp.services.timeout import (
1741 get_default_timeout_function,
1742@@ -1239,31 +1234,6 @@
1743 TwistedLayer._restore_signals()
1744
1745
1746-class GoogleServiceLayer(BaseLayer):
1747- """Tests for Google web service integration."""
1748-
1749- @classmethod
1750- def setUp(cls):
1751- google = GoogleServiceTestSetup()
1752- google.setUp()
1753-
1754- @classmethod
1755- def tearDown(cls):
1756- GoogleServiceTestSetup().tearDown()
1757-
1758- @classmethod
1759- def testSetUp(self):
1760- # We need to override BaseLayer.testSetUp(), or else we will
1761- # get a LayerIsolationError.
1762- pass
1763-
1764- @classmethod
1765- def testTearDown(self):
1766- # We need to override BaseLayer.testTearDown(), or else we will
1767- # get a LayerIsolationError.
1768- pass
1769-
1770-
1771 class BingServiceLayer(BaseLayer):
1772 """Tests for Bing web service integration."""
1773
1774@@ -1388,31 +1358,6 @@
1775 pass
1776
1777
1778-class GoogleLaunchpadFunctionalLayer(LaunchpadFunctionalLayer,
1779- GoogleServiceLayer):
1780- """Provides Google service in addition to LaunchpadFunctionalLayer."""
1781-
1782- @classmethod
1783- @profiled
1784- def setUp(cls):
1785- pass
1786-
1787- @classmethod
1788- @profiled
1789- def tearDown(cls):
1790- pass
1791-
1792- @classmethod
1793- @profiled
1794- def testSetUp(cls):
1795- pass
1796-
1797- @classmethod
1798- @profiled
1799- def testTearDown(cls):
1800- pass
1801-
1802-
1803 class BingLaunchpadFunctionalLayer(LaunchpadFunctionalLayer,
1804 BingServiceLayer):
1805 """Provides Bing service in addition to LaunchpadFunctionalLayer."""
1806@@ -1596,8 +1541,7 @@
1807 return self.request._orig_env
1808
1809
1810-class PageTestLayer(LaunchpadFunctionalLayer,
1811- BingServiceLayer, GoogleServiceLayer):
1812+class PageTestLayer(LaunchpadFunctionalLayer, BingServiceLayer):
1813 """Environment for page tests.
1814 """
1815
1816
1817=== modified file 'setup.py'
1818--- setup.py 2018-05-06 08:52:34 +0000
1819+++ setup.py 2018-05-21 21:36:59 +0000
1820@@ -291,8 +291,6 @@
1821 'build-twisted-plugin-cache = '
1822 'lp.services.twistedsupport.plugincache:main',
1823 'combine-css = lp.scripts.utilities.js.combinecss:main',
1824- 'googletestservice = '
1825- 'lp.services.sitesearch.googletestservice:main',
1826 'harness = lp.scripts.harness:python',
1827 'iharness = lp.scripts.harness:ipython',
1828 'ipy = IPython.frontend.terminal.ipapp:launch_new_instance',