Repository: rucio/rucio

Issue:
rucio upload api doesn't raise an error in some error cases
Motivation
----------

Modification
------------



Discussion:

Resolving patch:
diff --git a/lib/rucio/client/uploadclient.py b/lib/rucio/client/uploadclient.py
--- a/lib/rucio/client/uploadclient.py
+++ b/lib/rucio/client/uploadclient.py
@@ -30,8 +30,8 @@
 
 from rucio.client.client import Client
 from rucio.common.exception import (RucioException, RSEBlacklisted, DataIdentifierAlreadyExists,
-                                    DataIdentifierNotFound, ServiceUnavailable,
-                                    ResourceTemporaryUnavailable, InputValidationError)
+                                    DataIdentifierNotFound, NoFilesUploaded, NotAllFilesUploaded,
+                                    ResourceTemporaryUnavailable, ServiceUnavailable, InputValidationError)
 from rucio.common.utils import adler32, execute, generate_uuid, md5, send_trace
 from rucio.rse import rsemanager as rsemgr
 from rucio import version
@@ -209,6 +209,7 @@ def upload(self, sources_with_settings, summary_file_path=None):
 
         # clear this set again to ensure that we only try to register datasets once
         registered_dataset_dids = set()
+        num_succeeded = 0
         for file in files:
             basename = file['basename']
             logger.info('Preparing upload for file %s' % basename)
@@ -302,6 +303,7 @@ def upload(self, sources_with_settings, summary_file_path=None):
                         logger.debug('Exception: %s' % str(error))
 
                 if success:
+                    num_succeeded += 1
                     self.trace['transferEnd'] = time.time()
                     self.trace['clientState'] = 'DONE'
                     file['state'] = 'A'
@@ -312,7 +314,7 @@ def upload(self, sources_with_settings, summary_file_path=None):
                 else:
                     logger.error('Failed to upload file %s' % basename)
                     # TODO trace?
-                    continue  # skip attach_did and update_states for this file
+                    continue
             else:
                 logger.info('File already exists on RSE. Skipped upload')
 
@@ -346,3 +348,9 @@ def upload(self, sources_with_settings, summary_file_path=None):
                                                'md5': file['md5']}
             with open(summary_file_path, 'wb') as summary_file:
                 json.dump(final_summary, summary_file, sort_keys=True, indent=1)
+
+        if num_succeeded == 0:
+            raise NoFilesUploaded()
+        elif num_succeeded != len(files):
+            raise NotAllFilesUploaded()
+        return 0
diff --git a/lib/rucio/common/exception.py b/lib/rucio/common/exception.py
--- a/lib/rucio/common/exception.py
+++ b/lib/rucio/common/exception.py
@@ -66,7 +66,7 @@ def __str__(self):
 
 
 # Please insert new exceptions in alphabetic order
-# and add a new unique error code (current highest = 76)
+# and add a new unique error code (current highest = 80)
 
 class AccessDenied(RucioException):
     """
@@ -830,3 +830,23 @@ def __init__(self, *args, **kwargs):
         super(ServerConnectionException, self).__init__(args, kwargs)
         self._message = "Cannot connect to the Rucio server."
         self.error_code = 78
+
+
+class NoFilesUploaded(RucioException):
+    """
+    RucioException
+    """
+    def __init__(self, *args, **kwargs):
+        super(NoFilesUploaded, self).__init__(args, kwargs)
+        self._message = "None of the given files have been uploaded."
+        self.error_code = 79
+
+
+class NotAllFilesUploaded(RucioException):
+    """
+    RucioException
+    """
+    def __init__(self, *args, **kwargs):
+        super(NotAllFilesUploaded, self).__init__(args, kwargs)
+        self._message = "Not all of the given files have been uploaded."
+        self.error_code = 80


Test patch: