Browse Source

Make RPC tests cope with server-side timeout between requests

Python's httplib does not graciously handle disconnections from the http server, resulting in BadStatusLine errors.
See https://bugs.python.org/issue3566 "httplib persistent connections violate MUST in RFC2616 sec 8.1.4."

This was fixed in Python 3.5.

Work around it for now.
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
ddf98d1d84
  1. 36
      qa/rpc-tests/test_framework/authproxy.py

36
qa/rpc-tests/test_framework/authproxy.py

@ -106,6 +106,26 @@ class AuthServiceProxy(object):
name = "%s.%s" % (self.__service_name, name) name = "%s.%s" % (self.__service_name, name)
return AuthServiceProxy(self.__service_url, name, connection=self.__conn) return AuthServiceProxy(self.__service_url, name, connection=self.__conn)
def _request(self, method, path, postdata):
'''
Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout).
This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5.
'''
headers = {'Host': self.__url.hostname,
'User-Agent': USER_AGENT,
'Authorization': self.__auth_header,
'Content-type': 'application/json'}
try:
self.__conn.request(method, path, postdata, headers)
return self._get_response()
except httplib.BadStatusLine as e:
if e.line == "''": # if connection was closed, try again
self.__conn.close()
self.__conn.request(method, path, postdata, headers)
return self._get_response()
else:
raise
def __call__(self, *args): def __call__(self, *args):
AuthServiceProxy.__id_count += 1 AuthServiceProxy.__id_count += 1
@ -115,13 +135,7 @@ class AuthServiceProxy(object):
'method': self.__service_name, 'method': self.__service_name,
'params': args, 'params': args,
'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal)
self.__conn.request('POST', self.__url.path, postdata, response = self._request('POST', self.__url.path, postdata)
{'Host': self.__url.hostname,
'User-Agent': USER_AGENT,
'Authorization': self.__auth_header,
'Content-type': 'application/json'})
response = self._get_response()
if response['error'] is not None: if response['error'] is not None:
raise JSONRPCException(response['error']) raise JSONRPCException(response['error'])
elif 'result' not in response: elif 'result' not in response:
@ -133,13 +147,7 @@ class AuthServiceProxy(object):
def _batch(self, rpc_call_list): def _batch(self, rpc_call_list):
postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal) postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal)
log.debug("--> "+postdata) log.debug("--> "+postdata)
self.__conn.request('POST', self.__url.path, postdata, return self._request('POST', self.__url.path, postdata)
{'Host': self.__url.hostname,
'User-Agent': USER_AGENT,
'Authorization': self.__auth_header,
'Content-type': 'application/json'})
return self._get_response()
def _get_response(self): def _get_response(self):
http_response = self.__conn.getresponse() http_response = self.__conn.getresponse()

Loading…
Cancel
Save