Fixes hashing issues for py3.5

This fix uses encoding 'utf-8' before doing hashing.

Closes-Bug: 1697719
Co-Authored-By: Vladyslav Drok <vdrok@mirantis.com>
Change-Id: Ia61bed31ebd98032847504d6c96080330088d9ec
This commit is contained in:
Nisha Agarwal 2017-06-13 15:42:16 +00:00 committed by Vladyslav Drok
parent 870d909cc7
commit e14f963a22
2 changed files with 28 additions and 3 deletions

View File

@ -281,8 +281,13 @@ def hash_file(file_like_object, hash_algo='md5'):
:returns: a condensed digest of the bytes of contents.
"""
checksum = _get_hash_object(hash_algo)
for chunk in iter(lambda: file_like_object.read(32768), b''):
checksum.update(chunk)
while True:
chunk = file_like_object.read(32768)
if not chunk:
break
encoded_chunk = (chunk.encode(encoding='utf-8')
if isinstance(chunk, six.string_types) else chunk)
checksum.update(encoded_chunk)
return checksum.hexdigest()
@ -298,7 +303,9 @@ def file_has_content(path, content, hash_algo='md5'):
with open(path, 'rb') as existing:
file_hash_hex = hash_file(existing, hash_algo=hash_algo)
ref_hash = _get_hash_object(hash_algo)
ref_hash.update(content)
encoded_content = (content.encode(encoding='utf-8')
if isinstance(content, six.string_types) else content)
ref_hash.update(encoded_content)
return file_hash_hex == ref_hash.hexdigest()

View File

@ -127,6 +127,16 @@ class GenericUtilsTestCase(base.TestCase):
# | THEN |
self.assertEqual(expected, actual)
def test_hash_file_for_md5_not_binary(self):
# | GIVEN |
data = u'Mary had a little lamb, its fleece as white as sno\u0449'
file_like_object = six.StringIO(data)
expected = hashlib.md5(data.encode('utf-8')).hexdigest()
# | WHEN |
actual = utils.hash_file(file_like_object) # using default, 'md5'
# | THEN |
self.assertEqual(expected, actual)
def test_hash_file_for_sha1(self):
# | GIVEN |
data = b'Mary had a little lamb, its fleece as white as snow'
@ -163,6 +173,14 @@ class GenericUtilsTestCase(base.TestCase):
self.assertTrue(utils.file_has_content('foo', ref))
mopen.assert_called_once_with('foo', 'rb')
def test_file_has_content_equal_not_binary(self):
data = u'Mary had a little lamb, its fleece as white as sno\u0449'
ref = data
with mock.patch('ironic.common.utils.open',
mock.mock_open(read_data=data)) as mopen:
self.assertTrue(utils.file_has_content('foo', ref))
mopen.assert_called_once_with('foo', 'rb')
def test_file_has_content_differ(self):
data = b'Mary had a little lamb, its fleece as white as snow'
ref = data + b'!'