Skip to content

Commit

Permalink
Clients: Return information on download exception rucio#5250
Browse files Browse the repository at this point in the history
The different download functions in the `DownloadClient` return lists containing
the files and the states of the corresponding downloads. These states also
include failed states.

If an unknown exception is thrown in the `_download_item` method, the
corresponding file, which should be downloaded, is not present in the output
list. This leads to two problems; both can be solved by adding the file with the
download status `FAILED` to the output list:

- The number of files in the input queue and output queue is different, which
  throws an error. This is easily resolved by setting the file download status
  to `FAILED`. An error is later thrown.

- The client does not print the summary in case there is no items in the output
  queue. By adding the file to the output queue this problem is resolved.
  • Loading branch information
Joel Dierkes committed Apr 25, 2022
1 parent 47e93cf commit fd81b1f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/rucio/client/downloadclient.py
Expand Up @@ -424,6 +424,8 @@ def _download_worker(self, input_queue, output_queue, trace_custom_fields, trace
except Exception as error:
logger(logging.ERROR, '%sFailed to download item' % log_prefix)
logger(logging.DEBUG, error)
item["clientState"] = "FAILED"
output_queue.put(item)

@staticmethod
def _compute_actual_transfer_timeout(item):
Expand Down
30 changes: 29 additions & 1 deletion lib/rucio/tests/test_clients.py
Expand Up @@ -16,6 +16,7 @@
from __future__ import print_function

import unittest
from unittest.mock import patch
from datetime import datetime, timedelta

try:
Expand All @@ -33,9 +34,13 @@

from rucio.client.baseclient import BaseClient
from rucio.client.client import Client
from rucio.client.downloadclient import DownloadClient
from rucio.common.config import config_get, config_get_bool
from rucio.common.exception import CannotAuthenticate, ClientProtocolNotSupported, RucioException
from rucio.common.utils import get_tmp_dir
from rucio.common.types import InternalAccount, InternalScope
from rucio.common.utils import get_tmp_dir, generate_uuid as uuid
from rucio.core.rse import get_rse_id
from rucio.core.replica import add_replica
from rucio.tests.common import get_long_vo


Expand Down Expand Up @@ -195,3 +200,26 @@ def test_ping(self):
client = Client(account='root', ca_cert=self.cacert, auth_type='userpass', creds=creds, **self.vo)

print(client.ping())


class TestDownloadClient(unittest.TestCase):
def setUp(self):
if config_get_bool('common', 'multi_vo', raise_exception=False, default=False):
self.vo = {'vo': get_long_vo()}
else:
self.vo = {}

def test_download_exception_return_information(self):
scope = InternalScope('mock', **self.vo)
root = InternalAccount('root', **self.vo)
client = Client(account='root', ca_cert={}, auth_type='userpass', creds={}, **self.vo)
download_client = DownloadClient(client=client)

_file = 'file_%s' % uuid()
add_replica(rse_id=get_rse_id(rse="MOCK", **self.vo), scope=scope, name=_file, bytes_=1, account=root)

with patch('rucio.client.downloadclient.DownloadClient._download_item', side_effect=Exception()):
res = download_client.download_dids([{"did": "mock:" + _file}], deactivate_file_download_exceptions=True)

assert len(res) == 1
assert res[0]["clientState"] == "FAILED"

0 comments on commit fd81b1f

Please sign in to comment.