From: Mathieu Bridon <bochecha(a)daitauha.fr>
The only time we need to compute the hash of a source file is when we
interact with the lookaside cache, so it makes sense to have it there,
and remove some clutter from the main module.
However, the Commands._hash_file might be used by downstream, so let's
keep it for a while, make it use the new lookaside module, and emit a
deprecation warning.
---
src/pyrpkg/__init__.py | 27 ++++++------------------
src/pyrpkg/errors.py | 5 +++++
src/pyrpkg/lookaside.py | 34 ++++++++++++++++++++++++++++++
test/test_lookaside.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 100 insertions(+), 21 deletions(-)
create mode 100644 test/test_lookaside.py
diff --git a/src/pyrpkg/__init__.py b/src/pyrpkg/__init__.py
index b06c68b..e369db5 100644
--- a/src/pyrpkg/__init__.py
+++ b/src/pyrpkg/__init__.py
@@ -41,7 +41,7 @@ except ImportError:
from pyrpkg.errors import HashtypeMixingError, rpkgError, rpkgAuthError
from pyrpkg.lookaside import CGILookasideCache
from pyrpkg.sources import SourcesFile
-from pyrpkg.utils import cached_property
+from pyrpkg.utils import cached_property, warn_deprecated
# Setup our logger
@@ -773,24 +773,9 @@ class Commands(object):
return False
def _hash_file(self, file, hashtype):
- """Return the hash of a file given a hash type"""
-
- try:
- sum = hashlib.new(hashtype)
- except ValueError:
- raise rpkgError('Invalid hash type: %s' % hashtype)
-
- input = open(file, 'rb')
- # Loop through the file reading chunks at a time as to not
- # put the entire file in memory. That would suck for DVDs
- while True:
- chunk = input.read(8192) # magic number! Taking suggestions
- if not chunk:
- # we're done with the file
- break
- sum.update(chunk)
- input.close()
- return sum.hexdigest()
+ warn_deprecated(self.__class__.__name__, '_hash_file',
+ 'lookasidecache.hash_file')
+ return self.lookasidecache.hash_file(file, hashtype=hashtype)
def _run_command(self, cmd, shell=False, env=None, pipe=[], cwd=None):
"""Run the given command.
@@ -901,7 +886,7 @@ class Commands(object):
"""
# get the hash
- sum = self._hash_file(file, hashtype)
+ sum = self.lookasidecache.hash_file(file, hashtype=hashtype)
# now do the comparison
if sum == hash:
return True
@@ -2259,7 +2244,7 @@ class Commands(object):
uploaded = []
for f in files:
# TODO: Skip empty file needed?
- file_hash = self._hash_file(f, self.lookasidehash)
+ file_hash = self.lookasidecache.hash_file(f)
self.log.info("Uploading: %s %s" % (file_hash, f))
file_basename = os.path.basename(f)
diff --git a/src/pyrpkg/errors.py b/src/pyrpkg/errors.py
index ec67bdb..e9d481b 100644
--- a/src/pyrpkg/errors.py
+++ b/src/pyrpkg/errors.py
@@ -32,3 +32,8 @@ class HashtypeMixingError(rpkgError):
class MalformedLineError(rpkgError):
"""Raised when parsing a sources file with malformed
lines"""
pass
+
+
+class InvalidHashType(rpkgError):
+ """Raised when we don't know the requested hash
algorithm"""
+ pass
diff --git a/src/pyrpkg/lookaside.py b/src/pyrpkg/lookaside.py
index f7d191e..0a7e873 100644
--- a/src/pyrpkg/lookaside.py
+++ b/src/pyrpkg/lookaside.py
@@ -14,6 +14,11 @@ way it is done by Fedora, RHEL, and other distributions maintainers.
"""
+import hashlib
+
+from .errors import InvalidHashType
+
+
class CGILookasideCache(object):
"""A class to interact with a CGI-based lookaside
cache"""
def __init__(self, hashtype, download_url, upload_url):
@@ -28,3 +33,32 @@ class CGILookasideCache(object):
self.hashtype = hashtype
self.download_url = download_url
self.upload_url = upload_url
+
+ def hash_file(self, filename, hashtype=None):
+ """Compute the hash of a file
+
+ Args:
+ filename (str): The full path to the file. It is assumed to exist.
+ hashtype (str, optional): The hash algorithm to use. (e.g 'md5')
+ This defaults to the hashtype passed to the constructor.
+
+ Returns:
+ The hash digest.
+ """
+ if hashtype is None:
+ hashtype = self.hashtype
+
+ try:
+ sum = hashlib.new(hashtype)
+
+ except ValueError:
+ raise InvalidHashType(hashtype)
+
+ with open(filename, 'rb') as f:
+ chunk = f.read(8192)
+
+ while chunk:
+ sum.update(chunk)
+ chunk = f.read(8192)
+
+ return sum.hexdigest()
diff --git a/test/test_lookaside.py b/test/test_lookaside.py
new file mode 100644
index 0000000..aea886b
--- /dev/null
+++ b/test/test_lookaside.py
@@ -0,0 +1,55 @@
+# Copyright (c) 2015 - Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See
http://www.gnu.org/copyleft/gpl.html for
+# the full text of the license.
+
+
+import os
+import shutil
+import sys
+import tempfile
+import unittest
+
+old_path = list(sys.path)
+src_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../src')
+sys.path.insert(0, src_path)
+from pyrpkg.lookaside import CGILookasideCache
+from pyrpkg.errors import InvalidHashType
+sys.path = old_path
+
+
+class CGILookasideCacheTestCase(unittest.TestCase):
+ def setUp(self):
+ self.workdir = tempfile.mkdtemp(prefix='rpkg-tests.')
+ self.filename = os.path.join(self.workdir, self._testMethodName)
+
+ def tearDown(self):
+ shutil.rmtree(self.workdir)
+
+ def test_hash_file(self):
+ lc = CGILookasideCache('sha512', '_', '_')
+
+ with open(self.filename, 'w') as f:
+ f.write('something')
+
+ result = lc.hash_file(self.filename, 'md5')
+ self.assertEqual(result, '437b930db84b8079c2dd804a71936b5f')
+
+ result = lc.hash_file(self.filename)
+ self.assertEqual(result,
'983d43ddff6da90f6a5d3b6172446a1ffe228b803fe64fdd5dcfab5646078a896851fe82f623c9d6e5654b3d2f363a04ec17cfb62b607437a9c7c132d511e522')
# nopep8
+
+ def test_hash_file_invalid_hash_type(self):
+ lc = CGILookasideCache('sha512', '_', '_')
+ self.assertRaises(InvalidHashType, lc.hash_file, '_', 'sha42')
+
+ def test_hash_file_empty(self):
+ lc = CGILookasideCache('sha512', '_', '_')
+
+ with open(self.filename, 'w') as f:
+ f.write('')
+
+ result = lc.hash_file(self.filename, 'md5')
+ self.assertEqual(result, 'd41d8cd98f00b204e9800998ecf8427e')
--
2.1.0