Merge "Reuse checksum calculation from oslo"

This commit is contained in:
Zuul 2018-09-26 13:44:54 +00:00 committed by Gerrit Code Review
commit b8ffcc0f02
3 changed files with 10 additions and 80 deletions

View File

@ -31,6 +31,7 @@ import jinja2
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_log import log as logging from oslo_log import log as logging
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
from oslo_utils import fileutils
from oslo_utils import netutils from oslo_utils import netutils
from oslo_utils import timeutils from oslo_utils import timeutils
import pytz import pytz
@ -229,28 +230,6 @@ def _get_hash_object(hash_algo_name):
return getattr(hashlib, hash_algo_name)() 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)
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()
def file_has_content(path, content, hash_algo='md5'): def file_has_content(path, content, hash_algo='md5'):
"""Checks that content of the file is the same as provided reference. """Checks that content of the file is the same as provided reference.
@ -260,8 +239,7 @@ def file_has_content(path, content, hash_algo='md5'):
:returns: True if the hash of reference content is the same as :returns: True if the hash of reference content is the same as
the hash of file's content, False otherwise the hash of file's content, False otherwise
""" """
with open(path, 'rb') as existing: file_hash_hex = fileutils.compute_file_checksum(path, algorithm=hash_algo)
file_hash_hex = hash_file(existing, hash_algo=hash_algo)
ref_hash = _get_hash_object(hash_algo) ref_hash = _get_hash_object(hash_algo)
encoded_content = (content.encode(encoding='utf-8') encoded_content = (content.encode(encoding='utf-8')
if isinstance(content, six.string_types) else content) if isinstance(content, six.string_types) else content)

View File

@ -22,6 +22,7 @@ import tempfile
from ironic_lib import utils as ironic_utils from ironic_lib import utils as ironic_utils
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import fileutils
from oslo_utils import importutils from oslo_utils import importutils
import six import six
import six.moves.urllib.parse as urlparse import six.moves.urllib.parse as urlparse
@ -775,8 +776,8 @@ def verify_image_checksum(image_location, expected_checksum):
verification fails. verification fails.
""" """
try: try:
with open(image_location, 'rb') as fd: actual_checksum = fileutils.compute_file_checksum(image_location,
actual_checksum = utils.hash_file(fd) algorithm='md5')
except IOError as e: except IOError as e:
LOG.error("Error opening file: %(file)s", {'file': image_location}) LOG.error("Error opening file: %(file)s", {'file': image_location})
raise exception.ImageRefValidationFailed(image_href=image_location, raise exception.ImageRefValidationFailed(image_href=image_location,

View File

@ -15,7 +15,6 @@
import datetime import datetime
import errno import errno
import hashlib
import os import os
import os.path import os.path
import shutil import shutil
@ -26,7 +25,6 @@ import mock
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_config import cfg from oslo_config import cfg
from oslo_utils import netutils from oslo_utils import netutils
import six
from ironic.common import exception from ironic.common import exception
from ironic.common import utils from ironic.common import utils
@ -117,66 +115,19 @@ class GenericUtilsTestCase(base.TestCase):
utils._get_hash_object, utils._get_hash_object,
'hickory-dickory-dock') 'hickory-dickory-dock')
def test_hash_file_for_md5(self):
# | GIVEN |
data = b'Mary had a little lamb, its fleece as white as snow'
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_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'
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_file_has_content_equal(self): def test_file_has_content_equal(self):
data = b'Mary had a little lamb, its fleece as white as snow' data = b'Mary had a little lamb, its fleece as white as snow'
ref = data ref = data
with mock.patch('ironic.common.utils.open', with mock.patch('oslo_utils.fileutils.open',
mock.mock_open(read_data=data)) as mopen: mock.mock_open(read_data=data)) as mopen:
self.assertTrue(utils.file_has_content('foo', ref)) self.assertTrue(utils.file_has_content('foo', ref))
mopen.assert_called_once_with('foo', 'rb') mopen.assert_called_once_with('foo', 'rb')
def test_file_has_content_equal_not_binary(self): def test_file_has_content_equal_not_binary(self):
data = u'Mary had a little lamb, its fleece as white as sno\u0449' data = ('Mary had a little lamb, its fleece as white as '
'sno\u0449').encode('utf-8')
ref = data ref = data
with mock.patch('ironic.common.utils.open', with mock.patch('oslo_utils.fileutils.open',
mock.mock_open(read_data=data)) as mopen: mock.mock_open(read_data=data)) as mopen:
self.assertTrue(utils.file_has_content('foo', ref)) self.assertTrue(utils.file_has_content('foo', ref))
mopen.assert_called_once_with('foo', 'rb') mopen.assert_called_once_with('foo', 'rb')
@ -184,7 +135,7 @@ class GenericUtilsTestCase(base.TestCase):
def test_file_has_content_differ(self): def test_file_has_content_differ(self):
data = b'Mary had a little lamb, its fleece as white as snow' data = b'Mary had a little lamb, its fleece as white as snow'
ref = data + b'!' ref = data + b'!'
with mock.patch('ironic.common.utils.open', with mock.patch('oslo_utils.fileutils.open',
mock.mock_open(read_data=data)) as mopen: mock.mock_open(read_data=data)) as mopen:
self.assertFalse(utils.file_has_content('foo', ref)) self.assertFalse(utils.file_has_content('foo', ref))
mopen.assert_called_once_with('foo', 'rb') mopen.assert_called_once_with('foo', 'rb')