@mock.patch('codalab.lib.path_util.os', new_callable=lambda: None)
  def test_hash_directory(self, mock_os):
    tester = self
    directories = ['asdf', 'blah', 'this', 'is', 'not', 'sorted']
    files = ['foo', 'bar']
    relative_prefix = 'relative-'
    contents_hash_prefix = 'contents-hash-'

    # Compute the result of the the two-level hashing scheme on this bundle.
    directory_hash = hashlib.sha1()
    for directory in sorted(directories):
      path_hash = hashlib.sha1(relative_prefix + directory).hexdigest()
      directory_hash.update(path_hash)
    file_hash = hashlib.sha1()
    for file_name in sorted(files):
      name_hash = hashlib.sha1(relative_prefix + file_name).hexdigest()
      file_hash.update(name_hash)
      file_hash.update(contents_hash_prefix + file_name)
    overall_hash = hashlib.sha1()
    overall_hash.update(directory_hash.hexdigest())
    overall_hash.update(file_hash.hexdigest())
    expected_hash = overall_hash.hexdigest()

    # Mock the recursive-listing and file-hashing operations in path_util.
    def mock_recursive_ls(path):
      tester.assertEqual(path, self.test_path)
      return (directories, files)

    def mock_get_relative_path(root, path):
      tester.assertEqual(root, self.test_path)
      tester.assertIn(path, directories + files)
      return relative_prefix + path

    def mock_hash_file_contents(path):
      tester.assertIn(path, files)
      return contents_hash_prefix + path

    with mock.patch('codalab.lib.path_util.recursive_ls', mock_recursive_ls):
      with mock.patch('codalab.lib.path_util.get_relative_path', mock_get_relative_path):
        with mock.patch('codalab.lib.path_util.hash_file_contents', mock_hash_file_contents):
          actual_hash = path_util.hash_directory(self.test_path) 
    self.assertEqual(actual_hash, expected_hash)
Delete an image given its object id.
dataset/ETHPy150Open codalab/codalab-cli/tests/lib/path_util_test.py/PathUtilTest.test_hash_directory--crossover with--dataset/ETHPy150Open mozilla/kitsune/kitsune/upload/views.py/del_image_async