Augmenting the hashing strategy
It was only 'sha1' algorithm being used till now in ``hash_file`` method to create hash of the file contents. Need to add 'md5' to keep the consistency with that of IPA code base. Also, this method now supports all the algorithms hashlib does. As this method wasn't being used at all, therefore making the default algorithm to 'md5'. Will be used in oob firmware update (manual clean step) to verify the checksum of the images. Change-Id: I8159fd64d1c074bd539817a40900e34f8fae30d4
This commit is contained in:
parent
dab2fc347b
commit
1de89030a7
@ -390,9 +390,36 @@ def file_open(*args, **kwargs):
|
||||
return file(*args, **kwargs)
|
||||
|
||||
|
||||
def hash_file(file_like_object):
|
||||
"""Generate a hash for the contents of a file."""
|
||||
checksum = hashlib.sha1()
|
||||
def _get_hash_object(hash_algo_name):
|
||||
"""Create a hash object based on given algorithm.
|
||||
|
||||
:param hash_algo_name: name of the hashing algorithm.
|
||||
:raises: InvalidParameterValue, on unsupported or invalid input.
|
||||
:returns: a hash object based on the given named algorithm.
|
||||
"""
|
||||
algorithms = (hashlib.algorithms_guaranteed if six.PY3
|
||||
else hashlib.algorithms)
|
||||
if hash_algo_name not in algorithms:
|
||||
msg = (_("Unsupported/Invalid hash name '%s' provided.")
|
||||
% hash_algo_name)
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(msg)
|
||||
|
||||
return getattr(hashlib, hash_algo_name)()
|
||||
|
||||
|
||||
def hash_file(file_like_object, hash_algo='md5'):
|
||||
"""Generate a hash for the contents of a file.
|
||||
|
||||
It returns a hash of the file object as a string of double length,
|
||||
containing only hexadecimal digits. It supports all the algorithms
|
||||
hashlib does.
|
||||
:param file_like_object: file like object whose hash to be calculated.
|
||||
:param hash_algo: name of the hashing strategy, default being 'md5'.
|
||||
:raises: InvalidParameterValue, on unsupported or invalid input.
|
||||
: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)
|
||||
return checksum.hexdigest()
|
||||
|
@ -261,12 +261,68 @@ class GenericUtilsTestCase(base.TestCase):
|
||||
mock.ANY)
|
||||
fake_context_manager.__enter__.assert_called_once_with()
|
||||
|
||||
def test_hash_file(self):
|
||||
@mock.patch.object(utils, 'hashlib', autospec=True)
|
||||
def test__get_hash_object(self, hashlib_mock):
|
||||
algorithms_available = ('md5', 'sha1', 'sha224',
|
||||
'sha256', 'sha384', 'sha512')
|
||||
hashlib_mock.algorithms_guaranteed = algorithms_available
|
||||
hashlib_mock.algorithms = algorithms_available
|
||||
# | WHEN |
|
||||
utils._get_hash_object('md5')
|
||||
utils._get_hash_object('sha1')
|
||||
utils._get_hash_object('sha224')
|
||||
utils._get_hash_object('sha256')
|
||||
utils._get_hash_object('sha384')
|
||||
utils._get_hash_object('sha512')
|
||||
# | THEN |
|
||||
calls = [mock.call.md5(), mock.call.sha1(), mock.call.sha224(),
|
||||
mock.call.sha256(), mock.call.sha384(), mock.call.sha512()]
|
||||
hashlib_mock.assert_has_calls(calls)
|
||||
|
||||
def test__get_hash_object_throws_for_invalid_or_unsupported_hash_name(
|
||||
self):
|
||||
# | WHEN | & | THEN |
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
utils._get_hash_object,
|
||||
'hickory-dickory-dock')
|
||||
|
||||
def test_hash_file_for_md5(self):
|
||||
# | GIVEN |
|
||||
data = b'Mary had a little lamb, its fleece as white as snow'
|
||||
flo = six.BytesIO(data)
|
||||
h1 = utils.hash_file(flo)
|
||||
h2 = hashlib.sha1(data).hexdigest()
|
||||
self.assertEqual(h1, h2)
|
||||
file_like_object = six.BytesIO(data)
|
||||
expected = hashlib.md5(data).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'
|
||||
file_like_object = six.BytesIO(data)
|
||||
expected = hashlib.sha1(data).hexdigest()
|
||||
# | WHEN |
|
||||
actual = utils.hash_file(file_like_object, 'sha1')
|
||||
# | THEN |
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_hash_file_for_sha512(self):
|
||||
# | GIVEN |
|
||||
data = b'Mary had a little lamb, its fleece as white as snow'
|
||||
file_like_object = six.BytesIO(data)
|
||||
expected = hashlib.sha512(data).hexdigest()
|
||||
# | WHEN |
|
||||
actual = utils.hash_file(file_like_object, 'sha512')
|
||||
# | THEN |
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_hash_file_throws_for_invalid_or_unsupported_hash(self):
|
||||
# | GIVEN |
|
||||
data = b'Mary had a little lamb, its fleece as white as snow'
|
||||
file_like_object = six.BytesIO(data)
|
||||
# | WHEN | & | THEN |
|
||||
self.assertRaises(exception.InvalidParameterValue, utils.hash_file,
|
||||
file_like_object, 'hickory-dickory-dock')
|
||||
|
||||
def test_is_valid_boolstr(self):
|
||||
self.assertTrue(utils.is_valid_boolstr('true'))
|
||||
|
Loading…
Reference in New Issue
Block a user