Files
odoo_source/addons/website/tests/test_requests.py
T
Xavier Morel 841a5e7c2d [FIX] db handling being a pain in the ass
On runbot the base url dispatches into a unknown void of no db being
selected and the CMS thus 404s. For human beings there are additional
links to special subdomains setting the right db in the right place
(or maybe the right dbfilter, whatever) but that doesn't work right
for the crawler test suite.

Instead go through /web/ with a forced db selection, this *should* set
the db correctly in the user's session even if he's anonymous and thus
allows us to browse said db.

No idea if this fevered idea is actually going to work.

bzr revid: xmo@openerp.com-20131106115547-0ozlex09svkecrhb
2013-11-06 12:55:47 +01:00

121 lines
3.8 KiB
Python

# -*- coding: utf-8 -*-
import collections
import urllib
import urlparse
import unittest2
import urllib2
import lxml.html
from openerp import tools
from . import cases
__all__ = ['load_tests', 'CrawlSuite']
class RedirectHandler(urllib2.HTTPRedirectHandler):
"""
HTTPRedirectHandler is predicated upon HTTPErrorProcessor being used and
works by intercepting 3xy "errors".
Inherit from it to handle 3xy non-error responses instead, as we're not
using the error processor
"""
def http_response(self, request, response):
code, msg, hdrs = response.code, response.msg, response.info()
if 300 <= code < 400:
return self.parent.error(
'http', request, response, code, msg, hdrs)
return response
https_response = http_response
class CrawlSuite(unittest2.TestSuite):
""" Test suite crawling an openerp CMS instance and checking that all
internal links lead to a 200 response.
If a username and a password are provided, authenticates the user before
starting the crawl
"""
def __init__(self, user=None, password=None):
super(CrawlSuite, self).__init__()
self.opener = urllib2.OpenerDirector()
self.opener.add_handler(urllib2.UnknownHandler())
self.opener.add_handler(urllib2.HTTPHandler())
self.opener.add_handler(urllib2.HTTPSHandler())
self.opener.add_handler(RedirectHandler())
self.opener.add_handler(urllib2.HTTPCookieProcessor())
self._authenticate(user, password)
self.user = user
def _request(self, path):
return self.opener.open(urlparse.urlunsplit([
'http', 'localhost:%s' % tools.config['xmlrpc_port'],
path, '', ''
]))
def _authenticate(self, user, password):
# force tools.config['db_name'] in user session so opening `/` doesn't
# blow up in multidb situations
self.opener.open('http://localhost:{port}/web/?db={db}'.format(
port=tools.config['xmlrpc_port'],
db=urllib.quote_plus(tools.config['db_name']),
))
if user is not None:
url = 'http://localhost:{port}/login?{query}'.format(
port=tools.config['xmlrpc_port'],
query=urllib.urlencode({
'db': tools.config['db_name'],
'login': user,
'key': password,
})
)
auth = self.opener.open(url)
assert auth.getcode() < 400, "Auth failure %d" % auth.getcode()
def _wrapped_run(self, result, debug=False):
paths = collections.deque(['/'])
seen = set(paths)
while paths:
url = paths.popleft()
r = self._request(url)
cases.URLCase(self.user, url, r).run(result)
if r.info().gettype() != 'text/html':
continue
doc = lxml.html.fromstring(r.read())
for link in doc.xpath('//a[@href]'):
href = link.get('href')
# avoid repeats, even for links we won't crawl no need to
# bother splitting them if we've already ignored them
# previously
if href in seen: continue
seen.add(href)
parts = urlparse.urlsplit(href)
if parts.netloc or \
not parts.path.startswith('/') or \
parts.path == '/web' or\
parts.path.startswith('/web/') or \
(parts.scheme and parts.scheme not in ('http', 'https')):
continue
paths.append(href)
def load_tests(loader, base, _):
base.addTest(CrawlSuite())
# blog duplicate (&al?) are on links
base.addTest(CrawlSuite('admin', tools.config['admin_passwd']))
base.addTest(CrawlSuite('demo', 'demo'))
return base