diff --git a/swh/web/ui/service.py b/swh/web/ui/service.py index 91b4cc72..718fda0e 100644 --- a/swh/web/ui/service.py +++ b/swh/web/ui/service.py @@ -1,79 +1,78 @@ # Copyright (C) 2015 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from swh.core import hashutil from swh.web.ui import converters, main, query, upload def hash_and_search(filepath): """Hash the filepath's content as sha1, then search in storage if it exists. Args: Filepath of the file to hash and search. Returns: Tuple (hex sha1, found as True or false). The found boolean, according to whether the sha1 of the file is present or not. """ hash = hashutil.hashfile(filepath) - sha1 = hash['sha1'] - return (hashutil.hash_to_hex(sha1), - main.storage().content_exist({'sha1': sha1})) + return (hashutil.hash_to_hex(hash['sha1']), + main.storage().content_exist(hash)) def upload_and_search(file): """Upload a file and compute its hash. """ tmpdir, filename, filepath = upload.save_in_upload_folder(file) try: sha1, found = None, None if filepath: sha1, found = hash_and_search(filepath) return filename, sha1, found finally: # clean up if tmpdir: upload.cleanup(tmpdir) def lookup_hash(q): """Checks if the storage contains a given content checksum Args: query string Returns: True or False, according to whether the checksum is present or not """ (algo, hash) = query.parse_hash(q) return main.storage().content_exist({algo: hash}) def lookup_hash_origin(q): """Return information about the checksum contained in the query q. Args: query string Returns: True or False, according to whether the checksum is present or not """ algo, h = query.parse_hash(q) origin = main.storage().content_find_occurrence({algo: h}) return converters.from_origin(origin) def stat_counters(): """Return the stat counters for Software Heritage Returns: A dict mapping textual labels to integer values. """ return main.storage().stat_counters() diff --git a/swh/web/ui/tests/test_service.py b/swh/web/ui/tests/test_service.py index e0a4c2db..25d5be1d 100644 --- a/swh/web/ui/tests/test_service.py +++ b/swh/web/ui/tests/test_service.py @@ -1,113 +1,132 @@ # Copyright (C) 2015 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import unittest from nose.tools import istest -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch -from swh.core import hashutil +from swh.core.hashutil import hex_to_hash from swh.web.ui import service from swh.web.ui.tests import test_app class ServiceTestCase(unittest.TestCase): @classmethod def setUpClass(cls): cls.app, cls.storage = test_app.init_app() @istest def lookup_hash_does_not_exist(self): # given self.storage.content_exist = MagicMock(return_value=False) # when actual_lookup = service.lookup_hash( 'sha1:123caf10e9535160d90e874b45aa426de762f19f') # then self.assertFalse(actual_lookup) # check the function has been called with parameters self.storage.content_exist.assert_called_with({ 'sha1': - hashutil.hex_to_hash('123caf10e9535160d90e874b45aa426de762f19f')}) + hex_to_hash('123caf10e9535160d90e874b45aa426de762f19f')}) @istest def lookup_hash_exist(self): # given self.storage.content_exist = MagicMock(return_value=True) # when actual_lookup = service.lookup_hash( 'sha1:456caf10e9535160d90e874b45aa426de762f19f') # then self.assertTrue(actual_lookup) self.storage.content_exist.assert_called_with({ 'sha1': - hashutil.hex_to_hash('456caf10e9535160d90e874b45aa426de762f19f')}) + hex_to_hash('456caf10e9535160d90e874b45aa426de762f19f')}) @istest def lookup_hash_origin(self): # given self.storage.content_find_occurrence = MagicMock(return_value={ 'origin_type': 'sftp', 'origin_url': 'sftp://ftp.gnu.org/gnu/octave', 'branch': 'octavio-3.4.0.tar.gz', 'revision': b'\xb0L\xaf\x10\xe9SQ`\xd9\x0e\x87KE\xaaBm\xe7b\xf1\x9f', # noqa 'path': b'octavio-3.4.0/doc/interpreter/octave.html/doc_002dS_005fISREG.html' # noqa }) expected_origin = { 'origin_type': 'sftp', 'origin_url': 'sftp://ftp.gnu.org/gnu/octave', 'branch': 'octavio-3.4.0.tar.gz', 'revision': 'b04caf10e9535160d90e874b45aa426de762f19f', 'path': 'octavio-3.4.0/doc/interpreter/octave.html/doc' '_002dS_005fISREG.html' } # when actual_origin = service.lookup_hash_origin( 'sha1_git:456caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_origin, expected_origin) self.storage.content_find_occurrence.assert_called_with( {'sha1_git': - hashutil.hex_to_hash('456caf10e9535160d90e874b45aa426de762f19f')}) + hex_to_hash('456caf10e9535160d90e874b45aa426de762f19f')}) @istest def stat_counters(self): # given input_stats = { "content": 1770830, "directory": 211683, "directory_entry_dir": 209167, "directory_entry_file": 1807094, "directory_entry_rev": 0, "entity": 0, "entity_history": 0, "occurrence": 0, "occurrence_history": 19600, "origin": 1096, "person": 0, "release": 8584, "revision": 7792, "revision_history": 0, "skipped_content": 0 } self.storage.stat_counters = MagicMock(return_value=input_stats) # when actual_stats = service.stat_counters() # then expected_stats = input_stats self.assertEqual(actual_stats, expected_stats) self.storage.stat_counters.assert_called_with() + + @istest + def hash_and_search(self): + # given + self.storage.content_exist = MagicMock(return_value=False) + + bhash = hex_to_hash('456caf10e9535160d90e874b45aa426de762f19f') + # when + with patch( + 'swh.core.hashutil.hashfile', + return_value={'sha1': bhash}): + actual_hash, actual_search = service.hash_and_search('/some/path') + + # then + self.assertEqual(actual_hash, + '456caf10e9535160d90e874b45aa426de762f19f') + self.assertFalse(actual_search) + + self.storage.content_exist.assert_called_with({'sha1': bhash})