mirror of
https://github.com/python/cpython.git
synced 2025-11-02 11:08:57 +00:00
Import all implementations of the hash algorithms (OpenSSL & builtin) and run
the test suite across all that are available. Warns about extension modules that could not be imported when python was compiled with Py_DEBUG. That warning could be made fatal but I didn't want to do that initially as I suspect non setup.py based build processes (windows, any others?) won't compile them all conditionally based on the Py_DEBUG setting today.
This commit is contained in:
parent
92c58ae384
commit
6dcdcde2a8
1 changed files with 75 additions and 10 deletions
|
|
@ -8,14 +8,20 @@
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import StringIO
|
import StringIO
|
||||||
|
import sys
|
||||||
try:
|
try:
|
||||||
import threading
|
import threading
|
||||||
except ImportError:
|
except ImportError:
|
||||||
threading = None
|
threading = None
|
||||||
import unittest
|
import unittest
|
||||||
|
import warnings
|
||||||
from test import test_support
|
from test import test_support
|
||||||
from test.test_support import _4G, precisionbigmemtest
|
from test.test_support import _4G, precisionbigmemtest
|
||||||
|
|
||||||
|
# Were we compiled --with-pydebug or with #define Py_DEBUG?
|
||||||
|
COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount')
|
||||||
|
|
||||||
|
|
||||||
def hexstr(s):
|
def hexstr(s):
|
||||||
import string
|
import string
|
||||||
h = string.hexdigits
|
h = string.hexdigits
|
||||||
|
|
@ -31,6 +37,63 @@ class HashLibTestCase(unittest.TestCase):
|
||||||
'sha224', 'SHA224', 'sha256', 'SHA256',
|
'sha224', 'SHA224', 'sha256', 'SHA256',
|
||||||
'sha384', 'SHA384', 'sha512', 'SHA512' )
|
'sha384', 'SHA384', 'sha512', 'SHA512' )
|
||||||
|
|
||||||
|
_warn_on_extension_import = COMPILED_WITH_PYDEBUG
|
||||||
|
|
||||||
|
def _conditional_import_module(self, module_name):
|
||||||
|
"""Import a module and return a reference to it or None on failure."""
|
||||||
|
try:
|
||||||
|
exec('import '+module_name)
|
||||||
|
except ImportError, error:
|
||||||
|
if self._warn_on_extension_import:
|
||||||
|
warnings.warn('Did a C extension fail to compile? %s' % error)
|
||||||
|
return locals().get(module_name)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
algorithms = set()
|
||||||
|
for algorithm in self.supported_hash_names:
|
||||||
|
algorithms.add(algorithm.lower())
|
||||||
|
self.constructors_to_test = {}
|
||||||
|
for algorithm in algorithms:
|
||||||
|
self.constructors_to_test[algorithm] = set()
|
||||||
|
|
||||||
|
# For each algorithm, test the direct constructor and the use
|
||||||
|
# of hashlib.new given the algorithm name.
|
||||||
|
for algorithm, constructors in self.constructors_to_test.items():
|
||||||
|
constructors.add(getattr(hashlib, algorithm))
|
||||||
|
def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm):
|
||||||
|
if data is None:
|
||||||
|
return hashlib.new(_alg)
|
||||||
|
return hashlib.new(_alg, data)
|
||||||
|
constructors.add(_test_algorithm_via_hashlib_new)
|
||||||
|
|
||||||
|
_hashlib = self._conditional_import_module('_hashlib')
|
||||||
|
if _hashlib:
|
||||||
|
# These two algorithms should always be present when this module
|
||||||
|
# is compiled. If not, something was compiled wrong.
|
||||||
|
assert hasattr(_hashlib, 'openssl_md5')
|
||||||
|
assert hasattr(_hashlib, 'openssl_sha1')
|
||||||
|
for algorithm, constructors in self.constructors_to_test.items():
|
||||||
|
constructor = getattr(_hashlib, 'openssl_'+algorithm, None)
|
||||||
|
if constructor:
|
||||||
|
constructors.add(constructor)
|
||||||
|
|
||||||
|
_md5 = self._conditional_import_module('_md5')
|
||||||
|
if _md5:
|
||||||
|
self.constructors_to_test['md5'].add(_md5.new)
|
||||||
|
_sha = self._conditional_import_module('_sha')
|
||||||
|
if _sha:
|
||||||
|
self.constructors_to_test['sha1'].add(_sha.new)
|
||||||
|
_sha256 = self._conditional_import_module('_sha256')
|
||||||
|
if _sha256:
|
||||||
|
self.constructors_to_test['sha224'].add(_sha256.sha224)
|
||||||
|
self.constructors_to_test['sha256'].add(_sha256.sha256)
|
||||||
|
_sha512 = self._conditional_import_module('_sha512')
|
||||||
|
if _sha512:
|
||||||
|
self.constructors_to_test['sha384'].add(_sha512.sha384)
|
||||||
|
self.constructors_to_test['sha512'].add(_sha512.sha512)
|
||||||
|
|
||||||
|
super(HashLibTestCase, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def test_unknown_hash(self):
|
def test_unknown_hash(self):
|
||||||
try:
|
try:
|
||||||
hashlib.new('spam spam spam spam spam')
|
hashlib.new('spam spam spam spam spam')
|
||||||
|
|
@ -64,20 +127,22 @@ class HashLibTestCase(unittest.TestCase):
|
||||||
self.assertEqual(m1.digest(), m3.digest(), name+' new problem.')
|
self.assertEqual(m1.digest(), m3.digest(), name+' new problem.')
|
||||||
|
|
||||||
def check(self, name, data, digest):
|
def check(self, name, data, digest):
|
||||||
# test the direct constructors
|
constructors = self.constructors_to_test[name]
|
||||||
computed = getattr(hashlib, name)(data).hexdigest()
|
# 2 is for hashlib.name(...) and hashlib.new(name, ...)
|
||||||
self.assertEqual(computed, digest)
|
self.assertGreaterEqual(len(constructors), 2)
|
||||||
# test the general new() interface
|
for hash_object_constructor in constructors:
|
||||||
computed = hashlib.new(name, data).hexdigest()
|
computed = hash_object_constructor(data).hexdigest()
|
||||||
self.assertEqual(computed, digest)
|
self.assertEqual(
|
||||||
|
computed, digest,
|
||||||
|
"Hash algorithm %s constructed using %s returned hexdigest"
|
||||||
|
" %r for %d byte input data that should have hashed to %r."
|
||||||
|
% (name, hash_object_constructor,
|
||||||
|
computed, len(data), digest))
|
||||||
|
|
||||||
def check_unicode(self, algorithm_name):
|
def check_unicode(self, algorithm_name):
|
||||||
# Unicode objects are not allowed as input.
|
# Unicode objects are not allowed as input.
|
||||||
expected = hashlib.new(algorithm_name, str(u'spam')).hexdigest()
|
expected = hashlib.new(algorithm_name, str(u'spam')).hexdigest()
|
||||||
self.assertEqual(getattr(hashlib, algorithm_name)(u'spam').hexdigest(),
|
self.check(algorithm_name, u'spam', expected)
|
||||||
expected)
|
|
||||||
self.assertEqual(hashlib.new(algorithm_name, u'spam').hexdigest(),
|
|
||||||
expected)
|
|
||||||
|
|
||||||
def test_unicode(self):
|
def test_unicode(self):
|
||||||
# In python 2.x unicode is auto-encoded to the system default encoding
|
# In python 2.x unicode is auto-encoded to the system default encoding
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue