diff options
Diffstat (limited to 'Lib/test/test_hashlib.py')
| -rw-r--r-- | Lib/test/test_hashlib.py | 97 |
1 files changed, 71 insertions, 26 deletions
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 29d3a1c..c0470d6 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -9,6 +9,7 @@ import array import hashlib import itertools +import os import sys try: import threading @@ -37,7 +38,8 @@ class HashLibTestCase(unittest.TestCase): 'sha224', 'SHA224', 'sha256', 'SHA256', 'sha384', 'SHA384', 'sha512', 'SHA512' ) - _warn_on_extension_import = COMPILED_WITH_PYDEBUG + # Issue #14693: fallback modules are always compiled under POSIX + _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG def _conditional_import_module(self, module_name): """Import a module and return a reference to it or None on failure.""" @@ -94,10 +96,14 @@ class HashLibTestCase(unittest.TestCase): super(HashLibTestCase, self).__init__(*args, **kwargs) + @property + def hash_constructors(self): + constructors = self.constructors_to_test.values() + return itertools.chain.from_iterable(constructors) + def test_hash_array(self): a = array.array("b", range(10)) - constructors = self.constructors_to_test.values() - for cons in itertools.chain.from_iterable(constructors): + for cons in self.hash_constructors: c = cons(a) c.hexdigest() @@ -134,39 +140,57 @@ class HashLibTestCase(unittest.TestCase): self.assertRaises(TypeError, get_builtin_constructor, 3) def test_hexdigest(self): - for name in self.supported_hash_names: - h = hashlib.new(name) + for cons in self.hash_constructors: + h = cons() assert isinstance(h.digest(), bytes), name self.assertEqual(hexstr(h.digest()), h.hexdigest()) - def test_large_update(self): aas = b'a' * 128 bees = b'b' * 127 cees = b'c' * 126 + dees = b'd' * 2048 # HASHLIB_GIL_MINSIZE - for name in self.supported_hash_names: - m1 = hashlib.new(name) + for cons in self.hash_constructors: + m1 = cons() m1.update(aas) m1.update(bees) m1.update(cees) + m1.update(dees) - m2 = hashlib.new(name) - m2.update(aas + bees + cees) + m2 = cons() + m2.update(aas + bees + cees + dees) self.assertEqual(m1.digest(), m2.digest()) - def check(self, name, data, digest): + m3 = cons(aas + bees + cees + dees) + self.assertEqual(m1.digest(), m3.digest()) + + # verify copy() doesn't touch original + m4 = cons(aas + bees + cees) + m4_digest = m4.digest() + m4_copy = m4.copy() + m4_copy.update(dees) + self.assertEqual(m1.digest(), m4_copy.digest()) + self.assertEqual(m4.digest(), m4_digest) + + def check(self, name, data, hexdigest): + hexdigest = hexdigest.lower() constructors = self.constructors_to_test[name] # 2 is for hashlib.name(...) and hashlib.new(name, ...) self.assertGreaterEqual(len(constructors), 2) for hash_object_constructor in constructors: - computed = hash_object_constructor(data).hexdigest() + m = hash_object_constructor(data) + computed = m.hexdigest() self.assertEqual( - computed, digest, + computed, hexdigest, "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)) + computed, len(data), hexdigest)) + computed = m.digest() + digest = bytes.fromhex(hexdigest) + self.assertEqual(computed, digest) + self.assertEqual(len(digest), m.digest_size) def check_no_unicode(self, algorithm_name): # Unicode objects are not allowed as input. @@ -182,6 +206,24 @@ class HashLibTestCase(unittest.TestCase): self.check_no_unicode('sha384') self.check_no_unicode('sha512') + def check_blocksize_name(self, name, block_size=0, digest_size=0): + constructors = self.constructors_to_test[name] + for hash_object_constructor in constructors: + m = hash_object_constructor() + self.assertEqual(m.block_size, block_size) + self.assertEqual(m.digest_size, digest_size) + self.assertEqual(len(m.digest()), digest_size) + self.assertEqual(m.name.lower(), name.lower()) + self.assertIn(name.split("_")[0], repr(m).lower()) + + def test_blocksize_name(self): + self.check_blocksize_name('md5', 64, 16) + self.check_blocksize_name('sha1', 64, 20) + self.check_blocksize_name('sha224', 64, 28) + self.check_blocksize_name('sha256', 64, 32) + self.check_blocksize_name('sha384', 128, 48) + self.check_blocksize_name('sha512', 128, 64) + def test_case_md5_0(self): self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e') @@ -193,21 +235,15 @@ class HashLibTestCase(unittest.TestCase): b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'd174ab98d277d9f5a5611c2c9f419d9f') - @bigmemtest(size=_4G + 5, memuse=1) + @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems') + @bigmemtest(size=_4G + 5, memuse=1, dry_run=False) def test_case_md5_huge(self, size): - if size == _4G + 5: - try: - self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d') - except OverflowError: - pass # 32-bit arch + self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d') - @bigmemtest(size=_4G - 1, memuse=1) + @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems') + @bigmemtest(size=_4G - 1, memuse=1, dry_run=False) def test_case_md5_uintmax(self, size): - if size == _4G - 1: - try: - self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3') - except OverflowError: - pass # 32-bit arch + self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3') # use the three examples from Federal Information Processing Standards # Publication 180-1, Secure Hash Standard, 1995 April 17 @@ -321,6 +357,15 @@ class HashLibTestCase(unittest.TestCase): # for multithreaded operation (which is hardwired to 2048). gil_minsize = 2048 + for cons in self.hash_constructors: + m = cons() + m.update(b'1') + m.update(b'#' * gil_minsize) + m.update(b'1') + + m = cons(b'x' * gil_minsize) + m.update(b'1') + m = hashlib.md5() m.update(b'1') m.update(b'#' * gil_minsize) |
