Skip to content

Commit

Permalink
Merge #11513: [trivial] [tests] A few Python3 tidy ups
Browse files Browse the repository at this point in the history
f893085 [tests] Don't subclass from object for Python 3 (John Newbery)
8f9e362 [tests] authproxy.py: tidy up __init__() (John Newbery)
323d8f6 [tests] fix flake8 warnings in authproxy.py (John Newbery)
fc0176d [tests] use python3 for authproxy.py (John Newbery)

Pull request description:

  A few trivial tidyups in the test_framework:

  - the test_framework can only be run in Python3, so remove the py2/3 compatibility workarounds in authproxy.py
  - while there, do some general tidying up of the module - fix flake8 warnings, make initialization code more compact
  - All classes in Python3 are new-style. No need to explicitly inherit from `object`.

Tree-SHA512: d15c93aa4b47c1ad7d05baa7a564053cf0294932e178c95ef335380113f42e1af314978d07d3b107292a8e3496fd840535b5571a9164182feaa062a1e9ff8b73
  • Loading branch information
MarcoFalke committed Oct 17, 2017
2 parents 2c66cea + f893085 commit 14b860b
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 98 deletions.
2 changes: 1 addition & 1 deletion test/functional/p2p-fullblocktest.py
Expand Up @@ -20,7 +20,7 @@
from test_framework.script import *
import struct

class PreviousSpendableOutput(object):
class PreviousSpendableOutput():
def __init__(self, tx = CTransaction(), n = -1):
self.tx = tx
self.n = n # the output we're spending
Expand Down
2 changes: 1 addition & 1 deletion test/functional/p2p-segwit.py
Expand Up @@ -89,7 +89,7 @@ def test_witness_block(self, block, accepted, with_witness=True):
assert_equal(self.connection.rpc.getbestblockhash() == block.hash, accepted)

# Used to keep track of anyone-can-spend outputs that we can use in the tests
class UTXO(object):
class UTXO():
def __init__(self, sha256, n, nValue):
self.sha256 = sha256
self.n = n
Expand Down
59 changes: 20 additions & 39 deletions test/functional/test_framework/authproxy.py
Expand Up @@ -33,24 +33,17 @@
- uses standard Python json lib
"""

try:
import http.client as httplib
except ImportError:
import httplib
import base64
import decimal
import http.client
import json
import logging
import socket
import time
try:
import urllib.parse as urlparse
except ImportError:
import urlparse

USER_AGENT = "AuthServiceProxy/0.1"
import urllib.parse

HTTP_TIMEOUT = 30
USER_AGENT = "AuthServiceProxy/0.1"

log = logging.getLogger("BitcoinRPC")

Expand All @@ -60,7 +53,7 @@ def __init__(self, rpc_error):
errmsg = '%(message)s (%(code)i)' % rpc_error
except (KeyError, TypeError):
errmsg = ''
Exception.__init__(self, errmsg)
super().__init__(errmsg)
self.error = rpc_error


Expand All @@ -69,40 +62,28 @@ def EncodeDecimal(o):
return str(o)
raise TypeError(repr(o) + " is not JSON serializable")

class AuthServiceProxy(object):
class AuthServiceProxy():
__id_count = 0

# ensure_ascii: escape unicode as \uXXXX, passed to json.dumps
def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None, ensure_ascii=True):
self.__service_url = service_url
self._service_name = service_name
self.ensure_ascii = ensure_ascii # can be toggled on the fly by tests
self.__url = urlparse.urlparse(service_url)
if self.__url.port is None:
port = 80
else:
port = self.__url.port
(user, passwd) = (self.__url.username, self.__url.password)
try:
user = user.encode('utf8')
except AttributeError:
pass
try:
passwd = passwd.encode('utf8')
except AttributeError:
pass
self.ensure_ascii = ensure_ascii # can be toggled on the fly by tests
self.__url = urllib.parse.urlparse(service_url)
port = 80 if self.__url.port is None else self.__url.port
user = None if self.__url.username is None else self.__url.username.encode('utf8')
passwd = None if self.__url.password is None else self.__url.password.encode('utf8')
authpair = user + b':' + passwd
self.__auth_header = b'Basic ' + base64.b64encode(authpair)

if connection:
# Callables re-use the connection of the original proxy
self.__conn = connection
elif self.__url.scheme == 'https':
self.__conn = httplib.HTTPSConnection(self.__url.hostname, port,
timeout=timeout)
self.__conn = http.client.HTTPSConnection(self.__url.hostname, port, timeout=timeout)
else:
self.__conn = httplib.HTTPConnection(self.__url.hostname, port,
timeout=timeout)
self.__conn = http.client.HTTPConnection(self.__url.hostname, port, timeout=timeout)

def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
Expand All @@ -124,14 +105,14 @@ def _request(self, method, path, postdata):
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
except http.client.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
except (BrokenPipeError,ConnectionResetError):
except (BrokenPipeError, ConnectionResetError):
# Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset
# ConnectionResetError happens on FreeBSD with Python 3.4
self.__conn.close()
Expand All @@ -141,8 +122,8 @@ def _request(self, method, path, postdata):
def get_request(self, *args, **argsn):
AuthServiceProxy.__id_count += 1

log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name,
json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii)))
log.debug("-%s-> %s %s" % (AuthServiceProxy.__id_count, self._service_name,
json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii)))
if args and argsn:
raise ValueError('Cannot handle both named and positional arguments')
return {'version': '1.1',
Expand All @@ -163,7 +144,7 @@ def __call__(self, *args, **argsn):

def batch(self, rpc_call_list):
postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal, ensure_ascii=self.ensure_ascii)
log.debug("--> "+postdata)
log.debug("--> " + postdata)
return self._request('POST', self.__url.path, postdata.encode('utf-8'))

def _get_response(self):
Expand All @@ -190,9 +171,9 @@ def _get_response(self):
response = json.loads(responsedata, parse_float=decimal.Decimal)
elapsed = time.time() - req_start_time
if "error" in response and response["error"] is None:
log.debug("<-%s- [%.6f] %s"%(response["id"], elapsed, json.dumps(response["result"], default=EncodeDecimal, ensure_ascii=self.ensure_ascii)))
log.debug("<-%s- [%.6f] %s" % (response["id"], elapsed, json.dumps(response["result"], default=EncodeDecimal, ensure_ascii=self.ensure_ascii)))
else:
log.debug("<-- [%.6f] %s"%(elapsed,responsedata))
log.debug("<-- [%.6f] %s" % (elapsed, responsedata))
return response

def __truediv__(self, relative_uri):
Expand Down
4 changes: 2 additions & 2 deletions test/functional/test_framework/blockstore.py
Expand Up @@ -10,7 +10,7 @@

logger = logging.getLogger("TestFramework.blockstore")

class BlockStore(object):
class BlockStore():
"""BlockStore helper class.
BlockStore keeps a map of blocks and implements helper functions for
Expand Down Expand Up @@ -127,7 +127,7 @@ def get_locator(self, current_tip=None):
locator.vHave = r
return locator

class TxStore(object):
class TxStore():
def __init__(self, datadir):
self.txDB = dbmd.open(datadir + "/transactions", 'c')

Expand Down
6 changes: 3 additions & 3 deletions test/functional/test_framework/comptool.py
Expand Up @@ -27,7 +27,7 @@

global mininode_lock

class RejectResult(object):
class RejectResult():
"""Outcome that expects rejection of a transaction or block."""
def __init__(self, code, reason=b''):
self.code = code
Expand Down Expand Up @@ -156,13 +156,13 @@ def send_mempool(self):
# across all connections. (If outcome of final tx is specified as true
# or false, then only the last tx is tested against outcome.)

class TestInstance(object):
class TestInstance():
def __init__(self, objects=None, sync_every_block=True, sync_every_tx=False):
self.blocks_and_transactions = objects if objects else []
self.sync_every_block = sync_every_block
self.sync_every_tx = sync_every_tx

class TestManager(object):
class TestManager():

def __init__(self, testgen, datadir):
self.test_generator = testgen
Expand Down
2 changes: 1 addition & 1 deletion test/functional/test_framework/coverage.py
Expand Up @@ -14,7 +14,7 @@
REFERENCE_FILENAME = 'rpc_interface.txt'


class AuthServiceProxyWrapper(object):
class AuthServiceProxyWrapper():
"""
An object that wraps AuthServiceProxy to record specific RPC calls.
Expand Down
2 changes: 1 addition & 1 deletion test/functional/test_framework/key.py
Expand Up @@ -84,7 +84,7 @@ def _check_result(val, func, args):
ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
ssl.EC_KEY_new_by_curve_name.errcheck = _check_result

class CECKey(object):
class CECKey():
"""Wrapper around OpenSSL's EC_KEY"""

POINT_CONVERSION_COMPRESSED = 2
Expand Down

0 comments on commit 14b860b

Please sign in to comment.