示例#1
0
  def setBKRegistrationRequest(self, lfn, error='',
                               metaData={'Checksum': 'justSomething',
                                         'ChecksumType': 'ADLER32',
                                         'GUID': 'aGUID'}):
    """ Set a BK registration request for changing the replica flag.
        Uses the global request object (self.request).
    """
    if error:
      self.log.info('BK registration for %s failed with message: "%s" setting failover request' % (lfn, error))
    else:
      self.log.info('Setting BK registration request for %s' % (lfn))

    regFile = Operation()
    regFile.Type = 'RegisterFile'
    regFile.Catalog = 'BookkeepingDB'

    bkFile = File()
    bkFile.LFN = lfn
    # this should NOT be needed... but RMS complains!
    bkFile.PFN = lfn
    bkFile.GUID = metaData['GUID']
    bkFile.Checksum = metaData['Checksum']
    bkFile.ChecksumType = metaData['ChecksumType']

    regFile.addFile(bkFile)
    res = self.request.addOperation(regFile)
    if not res['OK']:
      raise RuntimeError(res['Message'])
示例#2
0
def myRequest():
    """Create a request and put it to the db"""

    request = Request()
    request.RequestName = 'myAwesomeRemovalRequest.xml'
    request.JobID = 0
    request.SourceComponent = "myScript"

    remove = Operation()
    remove.Type = "RemoveFile"

    lfn = "/ilc/user/s/sailer/test.txt"
    rmFile = File()
    rmFile.LFN = lfn
    remove.addFile(rmFile)

    request.addOperation(remove)
    isValid = RequestValidator().validate(request)
    if not isValid['OK']:
        raise RuntimeError("Failover request is not valid: %s" %
                           isValid['Message'])
    else:
        print "It is a GOGOGO"
        requestClient = ReqClient()
        result = requestClient.putRequest(request)
        print result
示例#3
0
  def __setFileReplicationRequest( self, lfn, targetSE, fileMetaDict, sourceSE = '' ):
    """ Sets a registration request.
    """
    self.log.info( 'Setting replication request for %s to %s' % ( lfn, targetSE ) )

    transfer = Operation()
    transfer.Type = "ReplicateAndRegister"
    transfer.TargetSE = targetSE
    if sourceSE:
      transfer.SourceSE = sourceSE

    trFile = File()
    trFile.LFN = lfn

    cksm = fileMetaDict.get( "Checksum", None )
    cksmType = fileMetaDict.get( "ChecksumType", None )
    if cksm and cksmType:
      trFile.Checksum = cksm
      trFile.ChecksumType = cksmType
    size = fileMetaDict.get( "Size", 0 )
    if size:
      trFile.Size = size
    guid = fileMetaDict.get( "GUID", "" )
    if guid:
      trFile.GUID = guid

    transfer.addFile( trFile )

    self.request.addOperation( transfer )

    return S_OK()
示例#4
0
  def __setRegistrationRequest( self, lfn, targetSE, fileDict, catalog ):
    """ Sets a registration request

    :param str lfn: LFN
    :param list se: list of SE
    :param list catalog: list of catalogs to use
    :param dict fileDict: file metadata
    """
    self.log.info( 'Setting registration request for %s at %s.' % ( lfn, targetSE ) )

    for cat in catalog:

      register = Operation()
      register.Type = "RegisterFile"
      register.Catalog = cat
      register.TargetSE = targetSE

      regFile = File()
      regFile.LFN = lfn
      regFile.Checksum = fileDict.get( "Checksum", "" )
      regFile.ChecksumType = fileDict.get( "ChecksumType", "" )
      regFile.Size = fileDict.get( "Size", 0 )
      regFile.GUID = fileDict.get( "GUID", "" )

      se = StorageElement( targetSE )
      pfn = se.getPfnForLfn( lfn )
      if not pfn["OK"]:
        self.log.error( "unable to get PFN for LFN: %s" % pfn["Message"] )
        return pfn
      regFile.PFN = pfn["Value"]

      register.addFile( regFile )
      self.request.addOperation( register )

    return S_OK()
    def getRegisterOperation(self,
                             opFile,
                             targetSE,
                             type='RegisterFile',
                             catalog=None):
        """ add RegisterReplica operation for file

    :param File opFile: operation file
    :param str targetSE: target SE
    """
        # # add RegisterReplica operation
        registerOperation = Operation()
        registerOperation.Type = type
        registerOperation.TargetSE = targetSE
        if catalog:
            registerOperation.Catalog = catalog

        registerFile = File()
        registerFile.LFN = opFile.LFN
        registerFile.PFN = StorageElement(targetSE).getPfnForLfn(
            opFile.LFN).get('Value', {}).get('Successful', {}).get(opFile.LFN)
        registerFile.GUID = opFile.GUID
        registerFile.Checksum = opFile.Checksum
        registerFile.ChecksumType = opFile.ChecksumType
        registerFile.Size = opFile.Size

        registerOperation.addFile(registerFile)
        return registerOperation
示例#6
0
    def test01ctor(self):
        """ test constructors and (de)serialisation """
        # # empty ctor
        self.assertEqual(isinstance(Operation(), Operation), True,
                         "empty ctor failed")

        # # using fromDict
        operation = Operation(self.fromDict)
        self.assertEqual(isinstance(operation, Operation), True,
                         "fromDict ctor failed")
        for key, value in self.fromDict.items():

            self.assertEqual(
                getattr(operation, key), value, "wrong attr value %s (%s) %s" %
                (key, getattr(operation, key), value))

        # # same with file
        operation = Operation(self.fromDict)
        operation.addFile(self.subFile)

        for key, value in self.fromDict.items():
            self.assertEqual(
                getattr(operation, key), value, "wrong attr value %s (%s) %s" %
                (key, getattr(operation, key), value))

        toJSON = operation.toJSON()
        self.assertEqual(toJSON["OK"], True, "JSON serialization failed")
示例#7
0
    def _createLogUploadRequest(self, targetSE, logFileLFN, uploadedSE):
        """ Set a request to upload job log files from the output sandbox
        Changed to be similar to LHCb createLogUploadRequest
        using LHCb LogUpload Request and Removal Request
    """
        self.log.info('Setting log upload request for %s at %s' %
                      (targetSE, logFileLFN))
        request = self._getRequestContainer()

        logUpload = Operation()
        logUpload.Type = "LogUpload"
        logUpload.TargetSE = targetSE

        upFile = File()
        upFile.LFN = logFileLFN
        logUpload.addFile(upFile)

        logRemoval = Operation()
        logRemoval.Type = 'RemoveFile'
        logRemoval.TargetSE = uploadedSE
        logRemoval.addFile(upFile)

        request.addOperation(logUpload)
        request.addOperation(logRemoval)

        self.workflow_commons['Request'] = request

        return S_OK()
示例#8
0
def test_ctor():
    """test constructors and (de)serialisation"""
    assert isinstance(Operation(), Operation), "empty ctor failed"

    # # using fromDict
    fromDict = {
        "Type": "replicateAndRegister",
        "TargetSE": "CERN-USER,PIC-USER",
        "SourceSE": None,
    }
    operation = Operation(fromDict)
    assert isinstance(operation, Operation), "fromDict ctor failed"
    for key, value in fromDict.items():
        assert getattr(operation,
                       key) == value, "wrong attr value %s (%s) %s" % (
                           key, getattr(operation, key), value)

    # # same with file
    operation = Operation(fromDict)
    operation.addFile(
        File({
            "LFN": "/lhcb/user/c/cibak/testFile",
            "Checksum": "1234567",
            "ChecksumType": "ADLER32",
            "Size": 1024,
            "Status": "Waiting",
        }))

    for key, value in fromDict.items():
        assert getattr(operation,
                       key) == value, "wrong attr value %s (%s) %s" % (
                           key, getattr(operation, key), value)

    toJSON = operation.toJSON()
    assert toJSON["OK"], "JSON serialization failed"
示例#9
0
    def __deleteSandboxFromExternalBackend(self, SEName, SEPFN):
        if self.getCSOption("DelayedExternalDeletion", True):
            gLogger.info("Setting deletion request")
            try:

                request = Request()
                request.RequestName = "RemoteSBDeletion:%s|%s:%s" % (
                    SEName, SEPFN, time.time())
                physicalRemoval = Operation()
                physicalRemoval.Type = "PhysicalRemoval"
                physicalRemoval.TargetSE = SEName
                fileToRemove = File()
                fileToRemove.PFN = SEPFN
                physicalRemoval.addFile(fileToRemove)
                request.addOperation(physicalRemoval)
                return ReqClient().putRequest(request)
            except Exception as e:
                gLogger.exception("Exception while setting deletion request")
                return S_ERROR("Cannot set deletion request: %s" % str(e))
        else:
            gLogger.info("Deleting external Sandbox")
            try:
                return StorageElement(SEName).removeFile(SEPFN)
            except Exception as e:
                gLogger.exception(
                    "RM raised an exception while trying to delete a remote sandbox"
                )
                return S_ERROR(
                    "RM raised an exception while trying to delete a remote sandbox"
                )
示例#10
0
    def _setFileReplicationRequest(self,
                                   lfn,
                                   targetSE,
                                   fileMetaDict,
                                   sourceSE=""):
        """Sets a registration request."""
        self.log.info("Setting ReplicateAndRegister request",
                      "for %s to %s" % (lfn, targetSE))

        transfer = Operation()
        transfer.Type = "ReplicateAndRegister"
        transfer.TargetSE = targetSE
        if sourceSE:
            transfer.SourceSE = sourceSE

        trFile = File()
        trFile.LFN = lfn

        cksm = fileMetaDict.get("Checksum", None)
        cksmType = fileMetaDict.get("ChecksumType", self.defaultChecksumType)
        if cksm and cksmType:
            trFile.Checksum = cksm
            trFile.ChecksumType = cksmType
        size = fileMetaDict.get("Size", 0)
        if size:
            trFile.Size = size
        guid = fileMetaDict.get("GUID", "")
        if guid:
            trFile.GUID = guid

        transfer.addFile(trFile)

        self.request.addOperation(transfer)

        return S_OK()
 def __submitRMSOp(self, target_se, lfns_chunk_dict, whichRMSOp='ReplicateAndRegister' ):
     """ target_se : SE name to which to replicate
         lfns_chunk_dict : LFNS dict with 100 lfns as key andeEach lfn has 'Size', 'Checksum'
         whichRMSOp: Choose from RMP operation - ReplicateAndRegister, ReplicateAndRemove, PutAndRegister
         """
 
     ## Setup request
     request = Request()
     request.RequestName = "DDM_"+ str(target_se) +  datetime.datetime.now().strftime("_%Y%m%d_%H%M%S")
     myOp = Operation()
     myOp.Type = whichRMSOp
     myOp.TargetSE = target_se
     ## Add LFNS to operations
     for lfn in lfns_chunk_dict.keys():
         opFile = File()
         opFile.LFN = lfn
         opFile.Size = lfns_chunk_dict[lfn]['Size']
         if "Checksum" in lfns_chunk_dict[lfn]:
             opFile.Checksum = lfns_chunk_dict[lfn]['Checksum']
             opFile.ChecksumType = 'ADLER32'
             ## Add file to operation
             myOp.addFile( opFile )
 
     request.addOperation( myOp )
     reqClient = ReqClient()
     putRequest = reqClient.putRequest( request )
     if not putRequest["OK"]:
         gLogger.error( "Unable to put request '%s': %s" % ( request.RequestName, putRequest["Message"] ) )
         return S_ERROR("Problem submitting to RMS.")
示例#12
0
  def __insertRegisterOperation( self, request, operation, toRegister ):
    """ add RegisterReplica operation

    :param Request request: request instance
    :param Operation transferOp: 'ReplicateAndRegister' operation for this FTSJob
    :param list toRegister: [ FTSDB.FTSFile, ... ] - files that failed to register
    """
    log = self.log.getSubLogger( "req_%s/%s/registerFiles" % ( request.RequestID, request.RequestName ) )

    byTarget = {}
    for ftsFile in toRegister:
      if ftsFile.TargetSE not in byTarget:
        byTarget.setdefault( ftsFile.TargetSE, [] )
      byTarget[ftsFile.TargetSE].append( ftsFile )
    log.info( "will create %s 'RegisterReplica' operations" % len( byTarget ) )

    for target, ftsFileList in byTarget.iteritems():
      log.info( "creating 'RegisterReplica' operation for targetSE %s with %s files..." % ( target,
                                                                                            len( ftsFileList ) ) )
      registerOperation = Operation()
      registerOperation.Type = "RegisterReplica"
      registerOperation.Status = "Waiting"
      registerOperation.TargetSE = target
      targetSE = StorageElement( target )
      for ftsFile in ftsFileList:
        opFile = File()
        opFile.LFN = ftsFile.LFN
        pfn = returnSingleResult( targetSE.getURL( ftsFile.LFN, protocol = self.registrationProtocols ) )
        if not pfn["OK"]:
          continue
        opFile.PFN = pfn["Value"]
        registerOperation.addFile( opFile )
      request.insertBefore( registerOperation, operation )

    return S_OK()
示例#13
0
  def test01ctor( self ):
    """ test constructors and (de)serialisation """
    # # empty ctor
    self.assertEqual( isinstance( Operation(), Operation ), True, "empty ctor failed" )

    # # using fromDict
    operation = Operation( self.fromDict )
    self.assertEqual( isinstance( operation, Operation ), True, "fromDict ctor failed" )
    for key, value in self.fromDict.items():

      self.assertEqual( getattr( operation, key ), value, "wrong attr value %s (%s) %s" % ( key,
                                                                                            getattr( operation, key ),
                                                                                            value ) )

    # # same with file
    operation = Operation( self.fromDict )
    operation.addFile( self.subFile )

    for key, value in self.fromDict.items():
      self.assertEqual( getattr( operation, key ), value, "wrong attr value %s (%s) %s" % ( key,
                                                                                            getattr( operation, key ),
                                                                                            value ) )

    toJSON = operation.toJSON()
    self.assertEqual( toJSON["OK"], True, "JSON serialization failed" )
示例#14
0
    def getRegisterOperation(self, opFile, targetSE, type="RegisterFile", catalog=None):
        """add RegisterReplica operation for file

        :param ~DIRAC.RequestManagementSystem.Client.File.File opFile: operation file
        :param str targetSE: target SE
        """
        # # add RegisterReplica operation
        registerOperation = Operation()
        registerOperation.Type = type
        registerOperation.TargetSE = targetSE
        if catalog:
            registerOperation.Catalog = catalog

        registerFile = File()
        registerFile.LFN = opFile.LFN
        registerFile.PFN = (
            StorageElement(targetSE)
            .getURL(opFile.LFN, protocol=self.registrationProtocols)
            .get("Value", {})
            .get("Successful", {})
            .get(opFile.LFN)
        )
        registerFile.GUID = opFile.GUID
        registerFile.Checksum = opFile.Checksum
        registerFile.ChecksumType = opFile.ChecksumType
        registerFile.Size = opFile.Size

        registerOperation.addFile(registerFile)
        return registerOperation
示例#15
0
  def __deleteSandboxFromExternalBackend( self, SEName, SEPFN ):
    if self.getCSOption( "DelayedExternalDeletion", True ):
      gLogger.info( "Setting deletion request" )
      try:

        request = Request()
        request.RequestName = "RemoteSBDeletion:%s|%s:%s" % ( SEName, SEPFN, time.time() )
        physicalRemoval = Operation()
        physicalRemoval.Type = "PhysicalRemoval"
        physicalRemoval.TargetSE = SEName
        fileToRemove = File()
        fileToRemove.PFN = SEPFN
        physicalRemoval.addFile( fileToRemove )
        request.addOperation( physicalRemoval )
        return ReqClient().putRequest( request )
      except Exception as e:
        gLogger.exception( "Exception while setting deletion request" )
        return S_ERROR( "Cannot set deletion request: %s" % str( e ) )
    else:
      gLogger.info( "Deleting external Sandbox" )
      try:
        return StorageElement( SEName ).removeFile( SEPFN )
      except Exception as e:
        gLogger.exception( "RM raised an exception while trying to delete a remote sandbox" )
        return S_ERROR( "RM raised an exception while trying to delete a remote sandbox" )
示例#16
0
def myRequest():
  """Create a request and put it to the db"""

  request = Request()
  request.RequestName = 'myAwesomeRemovalRequest.xml'
  request.JobID = 0
  request.SourceComponent = "myScript"

  remove = Operation()
  remove.Type = "RemoveFile"

  lfn = "/ilc/user/s/sailer/test.txt"
  rmFile = File()
  rmFile.LFN = lfn
  remove.addFile( rmFile )

  request.addOperation( remove )
  isValid = RequestValidator().validate( request )
  if not isValid['OK']:
    raise RuntimeError( "Failover request is not valid: %s" % isValid['Message'] )
  else:
    print("It is a GOGOGO")
    requestClient = ReqClient()
    result = requestClient.putRequest( request )
    print(result)
示例#17
0
def archiveRequestAndOp(listOfLFNs):
    """Return a tuple of the request and operation."""
    req = Request()
    req.RequestName = 'MyRequest'
    op = Operation()
    switches = {}
    archiveLFN = '/vo/tars/myTar.tar'
    op.Arguments = DEncode.encode({
        'SourceSE':
        switches.get('SourceSE', 'SOURCE-SE'),
        'TarballSE':
        switches.get('TarballSE', 'TARBALL-SE'),
        'RegisterDescendent':
        False,
        'ArchiveLFN':
        archiveLFN
    })
    op.Type = 'ArchiveFiles'
    for index, lfn in enumerate(listOfLFNs):
        oFile = File()
        oFile.LFN = lfn
        oFile.Size = index
        oFile.Checksum = '01130a%0d' % index
        oFile.ChecksumType = 'adler32'
        op.addFile(oFile)

    req.addOperation(op)
    return req, op
示例#18
0
  def __insertRegisterOperation( self, request, operation, toRegister ):
    """ add RegisterReplica operation

    :param Request request: request instance
    :param Operation transferOp: 'ReplicateAndRegister' operation for this FTSJob
    :param list toRegister: [ FTSDB.FTSFile, ... ] - files that failed to register
    """
    log = self.log.getSubLogger( "req_%s/%s/registerFiles" % ( request.RequestID, request.RequestName ) )

    byTarget = {}
    for ftsFile in toRegister:
      if ftsFile.TargetSE not in byTarget:
        byTarget.setdefault( ftsFile.TargetSE, [] )
      byTarget[ftsFile.TargetSE].append( ftsFile )
    log.info( "will create %s 'RegisterReplica' operations" % len( byTarget ) )

    for target, ftsFileList in byTarget.iteritems():
      log.info( "creating 'RegisterReplica' operation for targetSE %s with %s files..." % ( target,
                                                                                            len( ftsFileList ) ) )
      registerOperation = Operation()
      registerOperation.Type = "RegisterReplica"
      registerOperation.Status = "Waiting"
      registerOperation.TargetSE = target
      targetSE = StorageElement( target )
      for ftsFile in ftsFileList:
        opFile = File()
        opFile.LFN = ftsFile.LFN
        pfn = returnSingleResult( targetSE.getURL( ftsFile.LFN, protocol = self.registrationProtocols ) )
        if not pfn["OK"]:
          continue
        opFile.PFN = pfn["Value"]
        registerOperation.addFile( opFile )
      request.insertBefore( registerOperation, operation )

    return S_OK()
示例#19
0
def archiveRequestAndOp(listOfLFNs):
    """Return a tuple of the request and operation."""
    req = Request()
    req.RequestName = "MyRequest"
    op = Operation()
    switches = {}
    archiveLFN = "/vo/tars/myTar.tar"
    op.Arguments = DEncode.encode({
        "SourceSE":
        switches.get("SourceSE", "SOURCE-SE"),
        "TarballSE":
        switches.get("TarballSE", "TARBALL-SE"),
        "RegisterDescendent":
        False,
        "ArchiveLFN":
        archiveLFN,
    })
    op.Type = "ArchiveFiles"
    for index, lfn in enumerate(listOfLFNs):
        oFile = File()
        oFile.LFN = lfn
        oFile.Size = index
        oFile.Checksum = "01130a%0d" % index
        oFile.ChecksumType = "adler32"
        op.addFile(oFile)

    req.addOperation(op)
    return req, op
示例#20
0
  def _createLogUploadRequest(self, targetSE, logFileLFN, uploadedSE):
    """ Set a request to upload job log files from the output sandbox
        Changed to be similar to LHCb createLogUploadRequest
        using LHCb LogUpload Request and Removal Request
    """
    self.log.info('Setting log upload request for %s at %s' %(targetSE, logFileLFN))
    request = self._getRequestContainer()

    logUpload = Operation()
    logUpload.Type = "LogUpload"
    logUpload.TargetSE = targetSE

    upFile = File()
    upFile.LFN = logFileLFN
    logUpload.addFile( upFile )

    logRemoval = Operation()
    logRemoval.Type = 'RemoveFile'
    logRemoval.TargetSE = uploadedSE
    logRemoval.addFile( upFile )

    request.addOperation ( logUpload )
    request.addOperation ( logRemoval )

    self.workflow_commons['Request'] = request

    return S_OK()
示例#21
0
class MoveReplicaSuccess( ReqOpsTestCase ):

  def setUp(self):
    self.op = Operation()
    self.op.Type = "MoveFile"
    self.op.SourceSE = "%s,%s" % ( "sourceSE1", "sourceSE2" )
    self.op.TargetSE = "%s,%s" % ( "targetSE1", "targetSE2" )

    self.File = File()
    self.File.LFN = '/cta/file1'
    self.File.Size = 2L
    self.File.Checksum = '011300a2'
    self.File.ChecksumType = "adler32"
    self.op.addFile( self.File )

    self.req = Request()
    self.req.addOperation( self.op )
    self.mr = MoveReplica( self.op )

    self.mr.dm = MagicMock()
    self.mr.fc = MagicMock()

  # This test needs to be fixed. It currently fails because StorageElement is not mocked
  '''def test__dmTransfer( self ):

    successful = {}
    for sourceSE in self.op.sourceSEList:
      successful[sourceSE] = 'dips://' + sourceSE.lower() + ':9148/DataManagement/StorageElement' + self.File.LFN

    res = {'OK': True, 'Value': {'Successful': {self.File.LFN : successful}, 'Failed': {}}}
    self.mr.dm.getActiveReplicas.return_value = res

    res = {'OK': True, 'Value': {'Successful': {self.File.LFN : {'register': 0.1228799819946289, 'replicate': 9.872732877731323}}, 'Failed': {}}}
    self.mr.dm.replicateAndRegister.return_value = res

    res = self.mr.dmTransfer( self.File )
    self.assertTrue( res['OK'] )

    self.assertEqual( self.mr.operation.__files__[0].Status, 'Waiting' )
    self.assertEqual( self.mr.operation.Status, 'Waiting' )
    self.assertEqual( self.mr.request.Status, 'Waiting' )'''

  def test__dmRemoval( self ):

    res = {'OK': True, 'Value': {'Successful': { self.File.LFN : {'DIRACFileCatalog': True}}, 'Failed': {}}}
    self.mr.dm.removeReplica.return_value = res

    toRemoveDict = {self.File.LFN: self.File}
    targetSEs = self.op.sourceSEList

    res = self.mr.dmRemoval( toRemoveDict, targetSEs )
    self.assertTrue( res['OK'] )

    resvalue = dict( [ ( targetSE, '' ) for targetSE in targetSEs ] )
    self.assertEqual( res['Value'], {self.File.LFN: resvalue} )

    self.assertEqual( self.mr.operation.__files__[0].Status, 'Done' )
    self.assertEqual( self.mr.operation.Status, 'Done' )
    self.assertEqual( self.mr.request.Status, 'Done' )
示例#22
0
class MoveReplicaSuccess( ReqOpsTestCase ):

    def setUp(self):
      self.op = Operation()
      self.op.Type = "MoveFile"
      self.op.SourceSE = "%s,%s" % ( "sourceSE1", "sourceSE2" )
      self.op.TargetSE = "%s,%s" % ( "targetSE1", "targetSE2" )

      self.File = File()
      self.File.LFN = '/cta/file1'
      self.File.Size = 2L
      self.File.Checksum = '011300a2'
      self.File.ChecksumType = "adler32"
      self.op.addFile( self.File )

      self.req = Request()
      self.req.addOperation( self.op )
      self.mr = MoveReplica( self.op )

      self.mr.dm = MagicMock()
      self.mr.fc = MagicMock()

    # This test needs to be fixed. It currently fails because StorageElement is not mocked
    '''def test__dmTransfer( self ):

      successful = {}
      for sourceSE in self.op.sourceSEList:
        successful[sourceSE] = 'dips://' + sourceSE.lower() + ':9148/DataManagement/StorageElement' + self.File.LFN

      res = {'OK': True, 'Value': {'Successful': {self.File.LFN : successful}, 'Failed': {}}}
      self.mr.dm.getActiveReplicas.return_value = res

      res = {'OK': True, 'Value': {'Successful': {self.File.LFN : {'register': 0.1228799819946289, 'replicate': 9.872732877731323}}, 'Failed': {}}}
      self.mr.dm.replicateAndRegister.return_value = res

      res = self.mr.dmTransfer( self.File )
      self.assertTrue( res['OK'] )

      self.assertEqual( self.mr.operation.__files__[0].Status, 'Waiting' )
      self.assertEqual( self.mr.operation.Status, 'Waiting' )
      self.assertEqual( self.mr.request.Status, 'Waiting' )'''

    def test__dmRemoval( self ):

      res = {'OK': True, 'Value': {'Successful': { self.File.LFN : {'DIRACFileCatalog': True}}, 'Failed': {}}}
      self.mr.dm.removeReplica.return_value = res

      toRemoveDict = {self.File.LFN: self.File}
      targetSEs = self.op.sourceSEList

      res = self.mr.dmRemoval( toRemoveDict, targetSEs )
      self.assertTrue( res['OK'] )

      resvalue = dict( [ ( targetSE, '' ) for targetSE in targetSEs ] )
      self.assertEqual( res['Value'], {self.File.LFN: resvalue} )

      self.assertEqual( self.mr.operation.__files__[0].Status, 'Done' )
      self.assertEqual( self.mr.operation.Status, 'Done' )
      self.assertEqual( self.mr.request.Status, 'Done' )
示例#23
0
def createRequest(requestID, opType, opStatus, fileStatus, lfnError=" ",
                  lfn="/ilc/fake/lfn"):
  """Create a request."""
  req = Request({"RequestID": requestID})
  op = Operation({"Type": opType, "Status": opStatus})
  op.addFile(File({"LFN": lfn, "Status": fileStatus, "Error": lfnError}))
  req.addOperation(op)
  return req
示例#24
0
  def prepareTransformationTasks( self, transBody, taskDict, owner = '', ownerGroup = '', ownerDN = '' ):
    """ Prepare tasks, given a taskDict, that is created (with some manipulation) by the DB
    """
    if ( not owner ) or ( not ownerGroup ):
      res = getProxyInfo( False, False )
      if not res['OK']:
        return res
      proxyInfo = res['Value']
      owner = proxyInfo['username']
      ownerGroup = proxyInfo['group']

    if not ownerDN:
      res = getDNForUsername( owner )
      if not res['OK']:
        return res
      ownerDN = res['Value'][0]

    requestOperation = 'ReplicateAndRegister'
    if transBody:
      try:
        _requestType, requestOperation = transBody.split( ';' )
      except AttributeError:
        pass

    for taskID in sorted( taskDict ):
      paramDict = taskDict[taskID]
      if paramDict['InputData']:
        transID = paramDict['TransformationID']

        oRequest = Request()
        transfer = Operation()
        transfer.Type = requestOperation
        transfer.TargetSE = paramDict['TargetSE']

        if isinstance( paramDict['InputData'], list ):
          files = paramDict['InputData']
        elif isinstance( paramDict['InputData'], basestring ):
          files = paramDict['InputData'].split( ';' )
        for lfn in files:
          trFile = File()
          trFile.LFN = lfn

          transfer.addFile( trFile )

        oRequest.addOperation( transfer )
        oRequest.RequestName = _requestName( transID, taskID )
        oRequest.OwnerDN = ownerDN
        oRequest.OwnerGroup = ownerGroup

      isValid = self.requestValidator.validate( oRequest )
      if not isValid['OK']:
        return isValid

      taskDict[taskID]['TaskObject'] = oRequest

    return S_OK( taskDict )
示例#25
0
  def prepareTransformationTasks( self, transBody, taskDict, owner = '', ownerGroup = '', ownerDN = '' ):
    """ Prepare tasks, given a taskDict, that is created (with some manipulation) by the DB
    """
    if ( not owner ) or ( not ownerGroup ):
      res = getProxyInfo( False, False )
      if not res['OK']:
        return res
      proxyInfo = res['Value']
      owner = proxyInfo['username']
      ownerGroup = proxyInfo['group']

    if not ownerDN:
      res = getDNForUsername( owner )
      if not res['OK']:
        return res
      ownerDN = res['Value'][0]

    requestOperation = 'ReplicateAndRegister'
    if transBody:
      try:
        _requestType, requestOperation = transBody.split( ';' )
      except AttributeError:
        pass

    for taskID in sorted( taskDict ):
      paramDict = taskDict[taskID]
      if paramDict['InputData']:
        transID = paramDict['TransformationID']

        oRequest = Request()
        transfer = Operation()
        transfer.Type = requestOperation
        transfer.TargetSE = paramDict['TargetSE']

        if isinstance( paramDict['InputData'], list ):
          files = paramDict['InputData']
        elif isinstance( paramDict['InputData'], basestring ):
          files = paramDict['InputData'].split( ';' )
        for lfn in files:
          trFile = File()
          trFile.LFN = lfn

          transfer.addFile( trFile )

        oRequest.addOperation( transfer )
        oRequest.RequestName = _requestName( transID, taskID )
        oRequest.OwnerDN = ownerDN
        oRequest.OwnerGroup = ownerGroup

      isValid = self.requestValidator.validate( oRequest )
      if not isValid['OK']:
        return isValid

      taskDict[taskID]['TaskObject'] = oRequest

    return S_OK( taskDict )
示例#26
0
 def __setFileRemovalRequest(self, lfn):
   """ Sets a removal request for a file including all replicas.
   """
   self.log.info('Setting file removal request for %s' % lfn)
   removeFile = Operation()
   removeFile.Type = 'RemoveFile'
   rmFile = File()
   rmFile.LFN = lfn
   removeFile.addFile(rmFile)
   self.request.addOperation(removeFile)
示例#27
0
    def _multiOperationsBody(self, transJson, taskDict, ownerDN, ownerGroup):
        """ deal with a Request that has multiple operations

    :param transJson: list of lists of string and dictionaries, e.g.:

      .. code :: python

        body = [ ( "ReplicateAndRegister", { "SourceSE":"FOO-SRM", "TargetSE":"BAR-SRM" }),
                 ( "RemoveReplica", { "TargetSE":"FOO-SRM" } ),
               ]

    :param dict taskDict: dictionary of tasks, modified in this function
    :param str ownerDN: certificate DN used for the requests
    :param str onwerGroup: dirac group used for the requests

    :returns: None
    """
        failedTasks = []
        for taskID, task in taskDict.items():
            transID = task['TransformationID']
            if not task.get('InputData'):
                self._logError("Error creating request for task",
                               "%s, No input data" % taskID,
                               transID=transID)
                taskDict.pop(taskID)
                continue
            files = []

            oRequest = Request()
            if isinstance(task['InputData'], list):
                files = task['InputData']
            elif isinstance(task['InputData'], basestring):
                files = task['InputData'].split(';')

            # create the operations from the json structure
            for operationTuple in transJson:
                op = Operation()
                op.Type = operationTuple[0]
                for parameter, value in operationTuple[1].iteritems():
                    setattr(op, parameter, value)

                for lfn in files:
                    opFile = File()
                    opFile.LFN = lfn
                    op.addFile(opFile)

                oRequest.addOperation(op)

            result = self._assignRequestToTask(oRequest, taskDict, transID,
                                               taskID, ownerDN, ownerGroup)
            if not result['OK']:
                failedTasks.append(taskID)
        # Remove failed tasks
        for taskID in failedTasks:
            taskDict.pop(taskID)
示例#28
0
  def _multiOperationsBody(self, transJson, taskDict, ownerDN, ownerGroup):
    """ deal with a Request that has multiple operations

    :param transJson: list of lists of string and dictionaries, e.g.:

      .. code :: python

        body = [ ( "ReplicateAndRegister", { "SourceSE":"FOO-SRM", "TargetSE":"BAR-SRM" }),
                 ( "RemoveReplica", { "TargetSE":"FOO-SRM" } ),
               ]

    :param dict taskDict: dictionary of tasks, modified in this function
    :param str ownerDN: certificate DN used for the requests
    :param str onwerGroup: dirac group used for the requests

    :returns: None
    """
    failedTasks = []
    for taskID, task in taskDict.items():
      transID = task['TransformationID']
      if not task.get('InputData'):
        self._logError("Error creating request for task", "%s, No input data" % taskID, transID=transID)
        taskDict.pop(taskID)
        continue
      files = []

      oRequest = Request()
      if isinstance(task['InputData'], list):
        files = task['InputData']
      elif isinstance(task['InputData'], basestring):
        files = task['InputData'].split(';')

      # create the operations from the json structure
      for operationTuple in transJson:
        op = Operation()
        op.Type = operationTuple[0]
        for parameter, value in operationTuple[1].iteritems():
          setattr(op, parameter, value)

        for lfn in files:
          opFile = File()
          opFile.LFN = lfn
          op.addFile(opFile)

        oRequest.addOperation(op)

      result = self._assignRequestToTask(oRequest, taskDict, transID, taskID, ownerDN, ownerGroup)
      if not result['OK']:
        failedTasks.append(taskID)
    # Remove failed tasks
    for taskID in failedTasks:
      taskDict.pop(taskID)
示例#29
0
  def addRemovalRequests(self, lfnList):
    """Create removalRequests for lfns in lfnList and add it to the common request"""
    request = self._getRequestContainer()
    remove = Operation()
    remove.Type = "RemoveFile"

    for lfn in lfnList:
      rmFile = File()
      rmFile.LFN = lfn
      remove.addFile( rmFile )

    request.addOperation( remove )
    self.workflow_commons['Request'] = request
示例#30
0
  def addRemovalRequests(self, lfnList):
    """Create removalRequests for lfns in lfnList and add it to the common request"""
    request = self._getRequestContainer()
    remove = Operation()
    remove.Type = "RemoveFile"

    for lfn in lfnList:
      rmFile = File()
      rmFile.LFN = lfn
      remove.addFile( rmFile )

    request.addOperation( remove )
    self.workflow_commons['Request'] = request
示例#31
0
 def _setFileRemovalRequest(self, lfn, se="", pfn=""):
     """Sets a removal request for a file including all replicas."""
     remove = Operation()
     remove.Type = "RemoveFile"
     if se:
         remove.TargetSE = se
     rmFile = File()
     rmFile.LFN = lfn
     if pfn:
         rmFile.PFN = pfn
     remove.addFile(rmFile)
     self.request.addOperation(remove)
     return S_OK()
示例#32
0
  def buildRequest( self, owner, group, sourceSE, targetSE1, targetSE2 ):

    files = self.files( owner, group )

    putAndRegister = Operation()
    putAndRegister.Type = "PutAndRegister"
    putAndRegister.TargetSE = sourceSE
    for fname, lfn, size, checksum, guid in files:
      putFile = File()
      putFile.LFN = lfn
      putFile.PFN = fname
      putFile.Checksum = checksum
      putFile.ChecksumType = "adler32"
      putFile.Size = size
      putFile.GUID = guid
      putAndRegister.addFile( putFile )

    replicateAndRegister = Operation()
    replicateAndRegister.Type = "ReplicateAndRegister"
    replicateAndRegister.TargetSE = "%s,%s" % ( targetSE1, targetSE2 )
    for fname, lfn, size, checksum, guid in files:
      repFile = File()
      repFile.LFN = lfn
      repFile.Size = size
      repFile.Checksum = checksum
      repFile.ChecksumType = "adler32"
      replicateAndRegister.addFile( repFile )

    removeReplica = Operation()
    removeReplica.Type = "RemoveReplica"
    removeReplica.TargetSE = sourceSE
    for fname, lfn, size, checksum, guid in files:
      removeReplica.addFile( File( {"LFN": lfn } ) )

    removeFile = Operation()
    removeFile.Type = "RemoveFile"
    for fname, lfn, size, checksum, guid in files:
      removeFile.addFile( File( {"LFN": lfn } ) )

    removeFileInit = Operation()
    removeFileInit.Type = "RemoveFile"
    for fname, lfn, size, checksum, guid in files:
      removeFileInit.addFile( File( {"LFN": lfn } ) )

    req = Request()
    req.addOperation( removeFileInit )
    req.addOperation( putAndRegister )
    req.addOperation( replicateAndRegister )
    req.addOperation( removeReplica )
    req.addOperation( removeFile )
    return req
示例#33
0
    def buildRequest(self, owner, group, sourceSE, targetSE1, targetSE2):

        files = self.files(owner, group)

        putAndRegister = Operation()
        putAndRegister.Type = "PutAndRegister"
        putAndRegister.TargetSE = sourceSE
        for fname, lfn, size, checksum, guid in files:
            putFile = File()
            putFile.LFN = lfn
            putFile.PFN = fname
            putFile.Checksum = checksum
            putFile.ChecksumType = "adler32"
            putFile.Size = size
            putFile.GUID = guid
            putAndRegister.addFile(putFile)

        replicateAndRegister = Operation()
        replicateAndRegister.Type = "ReplicateAndRegister"
        replicateAndRegister.TargetSE = "%s,%s" % (targetSE1, targetSE2)
        for fname, lfn, size, checksum, guid in files:
            repFile = File()
            repFile.LFN = lfn
            repFile.Size = size
            repFile.Checksum = checksum
            repFile.ChecksumType = "adler32"
            replicateAndRegister.addFile(repFile)

        removeReplica = Operation()
        removeReplica.Type = "RemoveReplica"
        removeReplica.TargetSE = sourceSE
        for fname, lfn, size, checksum, guid in files:
            removeReplica.addFile(File({"LFN": lfn}))

        removeFile = Operation()
        removeFile.Type = "RemoveFile"
        for fname, lfn, size, checksum, guid in files:
            removeFile.addFile(File({"LFN": lfn}))

        removeFileInit = Operation()
        removeFileInit.Type = "RemoveFile"
        for fname, lfn, size, checksum, guid in files:
            removeFileInit.addFile(File({"LFN": lfn}))

        req = Request()
        req.addOperation(removeFileInit)
        req.addOperation(putAndRegister)
        req.addOperation(replicateAndRegister)
        req.addOperation(removeReplica)
        req.addOperation(removeFile)
        return req
示例#34
0
class RequestManagerHandlerTests( unittest.TestCase ):
  """
  .. class:: RequestManagerHandlerTests

  """

  def setUp( self ):
    """ test setup

    :param self: self reference
    """
    self.request = Request()
    self.request.RequestName = "RequestManagerHandlerTests"
    self.request.OwnerDN = "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=cibak/CN=605919/CN=Krzysztof Ciba"
    self.request.OwnerGroup = "dirac_user"
    self.operation = Operation()
    self.operation.Type = "ReplicateAndRegister"
    self.operation.TargetSE = "CERN-USER"
    self.file = File()
    self.file.LFN = "/lhcb/user/c/cibak/testFile"
    self.file.Checksum = "123456"
    self.file.ChecksumType = "ADLER32"
    self.request.addOperation( self.operation )
    self.operation.addFile( self.file )
    # # xml representation of a whole request
    self.xmlStr = self.request.toXML( True )["Value"]
    # # request client
    self.requestClient = RequestClient()


  def tearDown( self ):
    """ test case tear down """
    del self.request
    del self.operation
    del self.file
    del self.xmlStr

  def test01PutRequest( self ):
    """ test set request """
    put = self.requestClient.putRequest( self.request )
    self.assertEqual( put["OK"], True, "put failed" )

  def test02GetRequest( self ):
    """ test get request """
    get = self.requestClient.getRequest( self.request.RequestName )
    self.assertEqual( get["OK"], True, "get failed" )

  def test03DeleteRequest( self ):
    """ test delete request """
    delete = self.requestClient.deleteRequest( "test" )
    self.assertEqual( delete["OK"], True, "delete failed" )
示例#35
0
def test_StateMachine():
    """state machine"""
    op = Operation()
    assert op.Status == "Queued", "1. wrong status %s" % op.Status

    op.addFile(File({"Status": "Waiting"}))
    assert op.Status == "Queued", "2. wrong status %s" % op.Status

    op.addFile(File({"Status": "Scheduled"}))
    assert op.Status == "Scheduled", "3. wrong status %s" % op.Status

    op.addFile(File({"Status": "Done"}))
    assert op.Status == "Scheduled", "4. wrong status %s" % op.Status

    op.addFile(File({"Status": "Failed"}))
    assert op.Status == "Scheduled", "5. wrong status %s" % op.Status

    op[3].Status = "Scheduled"
    assert op.Status == "Scheduled", "6. wrong status %s" % op.Status

    op[0].Status = "Scheduled"
    assert op.Status == "Scheduled", "7. wrong status %s" % op.Status

    op[0].Status = "Waiting"
    assert op.Status == "Scheduled", "8. wrong status %s" % op.Status

    for f in op:
        f.Status = "Done"
    assert op.Status == "Done", "9. wrong status %s" % op.Status

    for f in op:
        f.Status = "Failed"
    assert op.Status == "Failed", "9. wrong status %s" % op.Status
示例#36
0
    def test04StateMachine(self):
        """ state machine """
        op = Operation()
        self.assertEqual(op.Status, "Queued", "1. wrong status %s" % op.Status)

        op.addFile(File({"Status": "Waiting"}))
        self.assertEqual(op.Status, "Queued", "2. wrong status %s" % op.Status)

        op.addFile(File({"Status": "Scheduled"}))
        self.assertEqual(op.Status, "Queued", "3. wrong status %s" % op.Status)

        op.addFile(File({"Status": "Done"}))
        self.assertEqual(op.Status, "Queued", "4. wrong status %s" % op.Status)

        op.addFile(File({"Status": "Failed"}))
        self.assertEqual(op.Status, "Failed", "5. wrong status %s" % op.Status)

        op[3].Status = "Scheduled"
        self.assertEqual(op.Status, "Queued", "6. wrong status %s" % op.Status)

        op[0].Status = "Scheduled"
        self.assertEqual(op.Status, "Scheduled",
                         "7. wrong status %s" % op.Status)

        op[0].Status = "Waiting"
        self.assertEqual(op.Status, "Queued", "8. wrong status %s" % op.Status)

        for f in op:
            f.Status = "Done"
        self.assertEqual(op.Status, "Done", "9. wrong status %s" % op.Status)
示例#37
0
  def test04StateMachine( self ):
    """ state machine """
    op = Operation()
    self.assertEqual( op.Status, "Queued", "1. wrong status %s" % op.Status )

    op.addFile( File( {"Status": "Waiting"} ) )
    self.assertEqual( op.Status, "Queued", "2. wrong status %s" % op.Status )

    op.addFile( File( {"Status": "Scheduled" } ) )
    self.assertEqual( op.Status, "Scheduled", "3. wrong status %s" % op.Status )

    op.addFile( File( {"Status": "Done" } ) )
    self.assertEqual( op.Status, "Scheduled", "4. wrong status %s" % op.Status )

    op.addFile( File( { "Status": "Failed" } ) )
    self.assertEqual( op.Status, "Scheduled", "5. wrong status %s" % op.Status )

    op[3].Status = "Scheduled"
    self.assertEqual( op.Status, "Scheduled", "6. wrong status %s" % op.Status )

    op[0].Status = "Scheduled"
    self.assertEqual( op.Status, "Scheduled", "7. wrong status %s" % op.Status )

    op[0].Status = "Waiting"
    self.assertEqual( op.Status, "Scheduled", "8. wrong status %s" % op.Status )

    for f in op:
      f.Status = "Done"
    self.assertEqual( op.Status, "Done", "9. wrong status %s" % op.Status )

    for f in op:
      f.Status = "Failed"
    self.assertEqual( op.Status, "Failed", "9. wrong status %s" % op.Status )
示例#38
0
def checkRequestAndOp(listOfLFNs):
    req = Request()
    req.RequestName = 'MyRequest'
    op = Operation()
    op.Type = 'CheckMigration'
    for index, lfn in enumerate(listOfLFNs):
        oFile = File()
        oFile.LFN = lfn
        oFile.Size = index
        oFile.Checksum = '01130a%0d' % index
        oFile.ChecksumType = 'adler32'
        op.addFile(oFile)
    req.addOperation(op)
    return req, op
示例#39
0
 def __setFileRemovalRequest( self, lfn, se = '', pfn = '' ):
   """ Sets a removal request for a file including all replicas.
   """
   remove = Operation()
   remove.Type = "RemoveFile"
   if se:
     remove.TargetSE = se
   rmFile = File()
   rmFile.LFN = lfn
   if pfn:
     rmFile.PFN = pfn
   remove.addFile( rmFile )
   self.request.addOperation( remove )
   return S_OK()
示例#40
0
class ReqClientTestCase( unittest.TestCase ):
  """
  .. class:: ReqClientTestCase

  """

  def setUp( self ):
    """ test case set up """

    gLogger.setLevel( 'INFO' )

    self.file = File()
    self.file.LFN = "/lhcb/user/c/cibak/testFile"
    self.file.Checksum = "123456"
    self.file.ChecksumType = "ADLER32"

    self.file2 = File()
    self.file2.LFN = "/lhcb/user/f/fstagni/testFile"
    self.file2.Checksum = "654321"
    self.file2.ChecksumType = "ADLER32"

    self.operation = Operation()
    self.operation.Type = "ReplicateAndRegister"
    self.operation.TargetSE = "CERN-USER"
    self.operation.addFile( self.file )
    self.operation.addFile( self.file2 )

    self.request = Request()
    self.request.RequestName = "RequestManagerHandlerTests"
    self.request.OwnerDN = "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=cibak/CN=605919/CN=Krzysztof Ciba"
    self.request.OwnerGroup = "dirac_user"
    self.request.JobID = 123
    self.request.addOperation( self.operation )

    # # JSON representation of a whole request
    self.jsonStr = self.request.toJSON()['Value']
    # # request client
    self.requestClient = ReqClient()

    self.stressRequests = 1000
    self.bulkRequest = 1000


  def tearDown( self ):
    """ clean up """
    del self.request
    del self.operation
    del self.file
    del self.jsonStr
示例#41
0
class ReqClientTestCase(unittest.TestCase):
  """
  .. class:: ReqClientTestCase

  """

  def setUp(self):
    """ test case set up """

    gLogger.setLevel('INFO')

    self.file = File()
    self.file.LFN = "/lhcb/user/c/cibak/testFile"
    self.file.Checksum = "123456"
    self.file.ChecksumType = "ADLER32"

    self.file2 = File()
    self.file2.LFN = "/lhcb/user/f/fstagni/testFile"
    self.file2.Checksum = "654321"
    self.file2.ChecksumType = "ADLER32"

    self.operation = Operation()
    self.operation.Type = "ReplicateAndRegister"
    self.operation.TargetSE = "CERN-USER"
    self.operation.addFile(self.file)
    self.operation.addFile(self.file2)

    proxyInfo = getProxyInfo()['Value']
    self.request = Request()
    self.request.RequestName = "RequestManagerHandlerTests"
    self.request.OwnerDN = proxyInfo['identity']
    self.request.OwnerGroup = proxyInfo['group']
    self.request.JobID = 123
    self.request.addOperation(self.operation)

    # # JSON representation of a whole request
    self.jsonStr = self.request.toJSON()['Value']
    # # request client
    self.requestClient = ReqClient()

    self.stressRequests = 1000
    self.bulkRequest = 1000

  def tearDown(self):
    """ clean up """
    del self.request
    del self.operation
    del self.file
    del self.jsonStr
示例#42
0
class ReqClientTestCase( unittest.TestCase ):
  """
  .. class:: ReqClientTestCase

  """

  def setUp( self ):
    """ test case set up """

    gLogger.setLevel( 'NOTICE' )

    self.file = File()
    self.file.LFN = "/lhcb/user/c/cibak/testFile"
    self.file.Checksum = "123456"
    self.file.ChecksumType = "ADLER32"

    self.file2 = File()
    self.file2.LFN = "/lhcb/user/f/fstagni/testFile"
    self.file2.Checksum = "654321"
    self.file2.ChecksumType = "ADLER32"

    self.operation = Operation()
    self.operation.Type = "ReplicateAndRegister"
    self.operation.TargetSE = "CERN-USER"
    self.operation.addFile( self.file )
    self.operation.addFile( self.file2 )

    self.request = Request()
    self.request.RequestName = "RequestManagerHandlerTests"
    self.request.OwnerDN = "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=cibak/CN=605919/CN=Krzysztof Ciba"
    self.request.OwnerGroup = "dirac_user"
    self.request.JobID = 123
    self.request.addOperation( self.operation )

    # # JSON representation of a whole request
    self.jsonStr = self.request.toJSON()['Value']
    # # request client
    self.requestClient = ReqClient()

    self.stressRequests = 1000
    self.bulkRequest = 1000


  def tearDown( self ):
    """ clean up """
    del self.request
    del self.operation
    del self.file
    del self.jsonStr
示例#43
0
def checkRequestAndOp(listOfLFNs):
    req = Request()
    req.RequestName = "MyRequest"
    op = Operation()
    op.Type = "CheckMigration"
    op.TargetSE = "Foo-SE"
    for index, lfn in enumerate(listOfLFNs):
        oFile = File()
        oFile.LFN = lfn
        oFile.Size = index
        oFile.Checksum = "01130a%0d" % index
        oFile.ChecksumType = "adler32"
        op.addFile(oFile)
    req.addOperation(op)
    return req, op
示例#44
0
    def _singleOperationsBody(self, transBody, taskDict, ownerDN, ownerGroup):
        """deal with a Request that has just one operation, as it was sofar

        :param transBody: string, can be an empty string
        :param dict taskDict: dictionary of tasks, modified in this function
        :param str ownerDN: certificate DN used for the requests
        :param str onwerGroup: dirac group used for the requests

        :returns: None
        """

        requestOperation = "ReplicateAndRegister"
        if transBody:
            try:
                _requestType, requestOperation = transBody.split(";")
            except AttributeError:
                pass
        failedTasks = []
        # Do not remove sorted, we might pop elements in the loop
        for taskID, task in taskDict.items():

            transID = task["TransformationID"]

            oRequest = Request()
            transfer = Operation()
            transfer.Type = requestOperation
            transfer.TargetSE = task["TargetSE"]

            # If there are input files
            if task.get("InputData"):
                if isinstance(task["InputData"], list):
                    files = task["InputData"]
                elif isinstance(task["InputData"], six.string_types):
                    files = task["InputData"].split(";")
                for lfn in files:
                    trFile = File()
                    trFile.LFN = lfn

                    transfer.addFile(trFile)

            oRequest.addOperation(transfer)
            result = self._assignRequestToTask(oRequest, taskDict, transID,
                                               taskID, ownerDN, ownerGroup)
            if not result["OK"]:
                failedTasks.append(taskID)
        # Remove failed tasks
        for taskID in failedTasks:
            taskDict.pop(taskID)
示例#45
0
  def _singleOperationsBody(self, transBody, taskDict, ownerDN, ownerGroup):
    """ deal with a Request that has just one operation, as it was sofar

    :param transBody: string, can be an empty string
    :param dict taskDict: dictionary of tasks, modified in this function
    :param str ownerDN: certificate DN used for the requests
    :param str onwerGroup: dirac group used for the requests

    :returns: None
    """

    requestOperation = 'ReplicateAndRegister'
    if transBody:
      try:
        _requestType, requestOperation = transBody.split(';')
      except AttributeError:
        pass
    failedTasks = []
    # Do not remove sorted, we might pop elements in the loop
    for taskID, task in taskDict.iteritems():

      transID = task['TransformationID']

      oRequest = Request()
      transfer = Operation()
      transfer.Type = requestOperation
      transfer.TargetSE = task['TargetSE']

      # If there are input files
      if task.get('InputData'):
        if isinstance(task['InputData'], list):
          files = task['InputData']
        elif isinstance(task['InputData'], basestring):
          files = task['InputData'].split(';')
        for lfn in files:
          trFile = File()
          trFile.LFN = lfn

          transfer.addFile(trFile)

      oRequest.addOperation(transfer)
      result = self._assignRequestToTask(oRequest, taskDict, transID, taskID, ownerDN, ownerGroup)
      if not result['OK']:
        failedTasks.append(taskID)
    # Remove failed tasks
    for taskID in failedTasks:
      taskDict.pop(taskID)
示例#46
0
    def __deleteSandboxFromExternalBackend(self, SEName, SEPFN):
        if self.getCSOption("DelayedExternalDeletion", True):
            gLogger.info("Setting deletion request")
            try:

                # We need the hostDN used in order to pass these credentials to the
                # SandboxStoreDB..
                hostCertLocation, _ = Locations.getHostCertificateAndKeyLocation(
                )
                hostCert = X509Certificate.X509Certificate()
                hostCert.loadFromFile(hostCertLocation)
                hostDN = hostCert.getSubjectDN().get("Value")

                # use the host authentication to fetch the data
                result = self.sandboxDB.getSandboxOwner(
                    SEName, SEPFN, hostDN, "hosts")
                if not result["OK"]:
                    return result
                _owner, ownerDN, ownerGroup = result["Value"]

                request = Request()
                request.RequestName = "RemoteSBDeletion:%s|%s:%s" % (
                    SEName, SEPFN, time.time())
                request.OwnerDN = ownerDN
                request.OwnerGroup = ownerGroup
                physicalRemoval = Operation()
                physicalRemoval.Type = "PhysicalRemoval"
                physicalRemoval.TargetSE = SEName
                fileToRemove = File()
                fileToRemove.PFN = SEPFN
                physicalRemoval.addFile(fileToRemove)
                request.addOperation(physicalRemoval)
                return ReqClient().putRequest(request)
            except Exception as e:
                gLogger.exception("Exception while setting deletion request")
                return S_ERROR(f"Cannot set deletion request: {e}")
        else:
            gLogger.info("Deleting external Sandbox")
            try:
                return StorageElement(SEName).removeFile(SEPFN)
            except Exception:
                gLogger.exception(
                    "RM raised an exception while trying to delete a remote sandbox"
                )
                return S_ERROR(
                    "RM raised an exception while trying to delete a remote sandbox"
                )
示例#47
0
class ReqClientTestCase(unittest.TestCase):
  """
  .. class:: ReqClientTestCase

  """

  def setUp(self):
    """ test case set up """

    gLogger.setLevel('INFO')

    self.file = File()
    self.file.LFN = "/lhcb/user/c/cibak/testFile"
    self.file.Checksum = "123456"
    self.file.ChecksumType = "ADLER32"

    self.file2 = File()
    self.file2.LFN = "/lhcb/user/f/fstagni/testFile"
    self.file2.Checksum = "654321"
    self.file2.ChecksumType = "ADLER32"

    self.operation = Operation()
    self.operation.Type = "ReplicateAndRegister"
    self.operation.TargetSE = "CERN-USER"
    self.operation.addFile(self.file)
    self.operation.addFile(self.file2)

    proxyInfo = getProxyInfo()['Value']
    self.request = Request()
    self.request.RequestName = "RequestManagerHandlerTests"
    self.request.OwnerDN = proxyInfo['identity']
    self.request.OwnerGroup = proxyInfo['group']
    self.request.JobID = 123
    self.request.addOperation(self.operation)

    # # JSON representation of a whole request
    self.jsonStr = self.request.toJSON()['Value']
    # # request client
    self.requestClient = ReqClient()

  def tearDown(self):
    """ clean up """
    del self.request
    del self.operation
    del self.file
    del self.jsonStr
示例#48
0
  def __setRemovalRequest( self, lfn, ownerDN, ownerGroup ):
    """ Set removal request with the given credentials
    """
    oRequest = Request()
    oRequest.OwnerDN = ownerDN
    oRequest.OwnerGroup = ownerGroup
    oRequest.RequestName = os.path.basename( lfn ).strip() + '_removal_request.xml'
    oRequest.SourceComponent = 'JobCleaningAgent'

    removeFile = Operation()
    removeFile.Type = 'RemoveFile'

    removedFile = File()
    removedFile.LFN = lfn

    removeFile.addFile( removedFile )
    oRequest.addOperation( removeFile )

    return ReqClient().putRequest( oRequest )
示例#49
0
  def __setRemovalRequest( self, lfn, ownerDN, ownerGroup ):
    """ Set removal request with the given credentials
    """
    oRequest = Request()
    oRequest.OwnerDN = ownerDN
    oRequest.OwnerGroup = ownerGroup
    oRequest.RequestName = os.path.basename( lfn ).strip() + '_removal_request.xml'
    oRequest.SourceComponent = 'JobCleaningAgent'

    removeFile = Operation()
    removeFile.Type = 'RemoveFile'

    removedFile = File()
    removedFile.LFN = lfn

    removeFile.addFile( removedFile )
    oRequest.addOperation( removeFile )

    return ReqClient().putRequest( oRequest )
示例#50
0
  def prepareTransformationTasks( self, transBody, taskDict, owner = '', ownerGroup = '' ):
    """ Prepare tasks, given a taskDict, that is created (with some manipulation) by the DB
    """
    requestOperation = 'ReplicateAndRegister'
    if transBody:
      try:
        _requestType, requestOperation = transBody.split( ';' )
      except AttributeError:
        pass

    for taskID in sorted( taskDict ):
      paramDict = taskDict[taskID]
      if paramDict['InputData']:
        transID = paramDict['TransformationID']

        oRequest = Request()
        transfer = Operation()
        transfer.Type = requestOperation
        transfer.TargetSE = paramDict['TargetSE']

        if type( paramDict['InputData'] ) == type( [] ):
          files = paramDict['InputData']
        elif type( paramDict['InputData'] ) == type( '' ):
          files = paramDict['InputData'].split( ';' )
        for lfn in files:
          trFile = File()
          trFile.LFN = lfn

          transfer.addFile( trFile )

        oRequest.addOperation( transfer )
        oRequest.RequestName = str( transID ).zfill( 8 ) + '_' + str( taskID ).zfill( 8 )
        oRequest.OwnerDN = owner
        oRequest.OwnerGroup = ownerGroup

      isValid = gRequestValidator.validate( oRequest )
      if not isValid['OK']:
        return isValid

      taskDict[taskID]['TaskObject'] = oRequest

    return S_OK( taskDict )
示例#51
0
  def getRegisterOperation( self, opFile, targetSE ):
    """ add RegisterReplica operation for file

    :param File opFile: operation file
    :param str targetSE: target SE
    """
    # # add RegisterReplica operation
    registerOperation = Operation()
    registerOperation.Type = "RegisterFile"
    registerOperation.TargetSE = targetSE

    registerFile = File()
    registerFile.LFN = opFile.LFN
    registerFile.PFN = opFile.PFN
    registerFile.GUID = opFile.GUID
    registerFile.Checksum = opFile.Checksum
    registerFile.ChecksumType = opFile.ChecksumType
    registerFile.Size = opFile.Size

    registerOperation.addFile( registerFile )
    return registerOperation
示例#52
0
  def __setReplicaRemovalRequest( self, lfn, se ):
    """ Sets a removal request for a replica.

    :param str lfn: LFN
    :param se:
    """
    if type( se ) == str:
      se = ",".join( [ se.strip() for se in se.split( "," ) if se.strip() ] )

    removeReplica = Operation()

    removeReplica.Type = "RemoveReplica"
    removeReplica.TargetSE = se

    replicaToRemove = File()
    replicaToRemove.LFN = lfn

    removeReplica.addFile( replicaToRemove )

    self.request.addOperation( removeReplica )
    return S_OK()
  def addRegisterReplica( self, opFile, targetSE ):
    """ add RegisterReplica operation for file

    :param File opFile: operation file
    :param str targetSE: target SE
    """
    # # add RegisterReplica operation
    registerOperation = Operation()
    registerOperation.Type = "RegisterFile"
    registerOperation.TargetSE = targetSE

    registerFile = File()
    registerFile.LFN = opFile.LFN
    registerFile.PFN = opFile.PFN
    registerFile.GUID = opFile.GUID
    registerFile.Checksum = opFile.Checksum
    registerFile.ChecksumType = opFile.ChecksumType
    registerFile.Size = opFile.Size

    registerOperation.addFile( registerFile )
    self.request.insertAfter( registerOperation, self.operation )
    return S_OK()
示例#54
0
  def _setRegistrationRequest( self, lfn, targetSE, fileDict, catalog ):
    """ Sets a registration request

    :param str lfn: LFN
    :param list se: list of SE (or just string)
    :param list catalog: list (or string) of catalogs to use
    :param dict fileDict: file metadata
    """
    self.log.info( 'Setting registration request for %s at %s.' % ( lfn, targetSE ) )

    if not isinstance( catalog, list ):
      catalog = [catalog]

    for cat in catalog:

      register = Operation()
      register.Type = "RegisterFile"
      register.Catalog = cat
      register.TargetSE = targetSE

      regFile = File()
      regFile.LFN = lfn
      regFile.Checksum = fileDict.get( "Checksum", "" )
      regFile.ChecksumType = fileDict.get( "ChecksumType", self.defaultChecksumType )
      regFile.Size = fileDict.get( "Size", 0 )
      regFile.GUID = fileDict.get( "GUID", "" )

      se = StorageElement( targetSE )
      pfn = se.getURL( lfn, self.registrationProtocols )
      if not pfn["OK"] or lfn not in pfn["Value"]['Successful']:
        self.log.error( "Unable to get PFN for LFN", "%s" % pfn.get( 'Message', pfn.get( 'Value', {} ).get( 'Failed', {} ).get( lfn ) ) )
        return pfn
      regFile.PFN = pfn["Value"]['Successful'][lfn]

      register.addFile( regFile )
      self.request.addOperation( register )

    return S_OK()
示例#55
0
  def getRegisterOperation( self, opFile, targetSE, type = 'RegisterFile', catalog = None ):
    """ add RegisterReplica operation for file

    :param File opFile: operation file
    :param str targetSE: target SE
    """
    # # add RegisterReplica operation
    registerOperation = Operation()
    registerOperation.Type = type
    registerOperation.TargetSE = targetSE
    if catalog:
      registerOperation.Catalog = catalog

    registerFile = File()
    registerFile.LFN = opFile.LFN
    registerFile.PFN = StorageElement( targetSE ).getURL( opFile.LFN, protocol = self.registrationProtocols ).get( 'Value', {} ).get( 'Successful', {} ).get( opFile.LFN )
    registerFile.GUID = opFile.GUID
    registerFile.Checksum = opFile.Checksum
    registerFile.ChecksumType = opFile.ChecksumType
    registerFile.Size = opFile.Size

    registerOperation.addFile( registerFile )
    return registerOperation
    print "Can't get file metadata: %s" % res['Message']
    DIRAC.exit( 1 )
  if res['Value']['Failed']:
    print "Could not get the file metadata of the following, so skipping them:"
    for fFile in res['Value']['Failed']:
      print fFile

  lfnMetadata = res['Value']['Successful']

  for lfn in lfnMetadata:
    rarFile = File()
    rarFile.LFN = lfn
    rarFile.Size = lfnMetadata[lfn]['Size']
    rarFile.Checksum = lfnMetadata[lfn]['Checksum']
    rarFile.GUID = lfnMetadata[lfn]['GUID']
    rarFile.ChecksumType = 'ADLER32'
    replicateAndRegister.addFile( rarFile )

  oRequest.addOperation( replicateAndRegister )
  isValid = RequestValidator().validate( oRequest )
  if not isValid['OK']:
    print "Request is not valid: ", isValid['Message']
    DIRAC.exit( 1 )

  result = reqClient.putRequest( oRequest )
  if result['OK']:
    print "Request %d submitted successfully" % result['Value']
  else:
    print "Failed to submit Request: ", result['Message']

示例#57
0
  def getRequest( self, requestName = '', assigned = True ):
    """ read request for execution

    :param str requestName: request's name (default None)
    """
    requestID = None
    if requestName:
      self.log.info( "getRequest: selecting request '%s'" % requestName )
      reqIDQuery = "SELECT `RequestID`, `Status` FROM `Request` WHERE `RequestName` = '%s';" % str( requestName )
      reqID = self._transaction( reqIDQuery )
      if not reqID["OK"]:
        self.log.error( "getRequest: %s" % reqID["Message"] )
        return reqID
      requestID = reqID["Value"][reqIDQuery][0]["RequestID"] if "RequestID" in reqID["Value"][reqIDQuery][0] else None
      status = reqID["Value"][reqIDQuery][0]["Status"] if "Status" in reqID["Value"][reqIDQuery][0] else None
      if not all( ( requestID, status ) ):
        return S_ERROR( "getRequest: request '%s' not exists" % requestName )
      if requestID and status and status == "Assigned" and assigned:
        return S_ERROR( "getRequest: status of request '%s' is 'Assigned', request cannot be selected" % requestName )
    else:
      reqIDsQuery = "SELECT `RequestID` FROM `Request` WHERE `Status` = 'Waiting' ORDER BY `LastUpdate` ASC LIMIT 100;"
      reqIDs = self._transaction( reqIDsQuery )
      if not reqIDs["OK"]:
        self.log.error( "getRequest: %s" % reqIDs["Message"] )
        return reqIDs
      reqIDs = reqIDs["Value"][reqIDsQuery]
      reqIDs = [ reqID["RequestID"] for reqID in reqIDs ]
      if not reqIDs:
        return S_OK()
      random.shuffle( reqIDs )
      requestID = reqIDs[0]

    selectQuery = [ "SELECT * FROM `Request` WHERE `RequestID` = %s;" % requestID,
                    "SELECT * FROM `Operation` WHERE `RequestID` = %s;" % requestID ]
    selectReq = self._transaction( selectQuery )
    if not selectReq["OK"]:
      self.log.error( "getRequest: %s" % selectReq["Message"] )
      return S_ERROR( selectReq["Message"] )
    selectReq = selectReq["Value"]

    request = Request( selectReq[selectQuery[0]][0] )
    for records in sorted( selectReq[selectQuery[1]], key = lambda k: k["Order"] ):
      # # order is ro, remove
      del records["Order"]
      operation = Operation( records )
      getFilesQuery = "SELECT * FROM `File` WHERE `OperationID` = %s;" % operation.OperationID
      getFiles = self._transaction( getFilesQuery )
      if not getFiles["OK"]:
        self.log.error( "getRequest: %s" % getFiles["Message"] )
        return getFiles
      getFiles = getFiles["Value"][getFilesQuery]
      for getFile in getFiles:
        getFileDict = dict( [ ( key, value ) for key, value in getFile.items() if value != None ] )
        operation.addFile( File( getFileDict ) )
      request.addOperation( operation )

    if assigned:
      setAssigned = self._transaction( "UPDATE `Request` SET `Status` = 'Assigned' WHERE RequestID = %s;" % requestID )
      if not setAssigned["OK"]:
        self.log.error( "getRequest: %s" % setAssigned["Message"] )
        return setAssigned

    return S_OK( request )
    replicateAndRegister.Type = "ReplicateAndRegister"
    replicateAndRegister.TargetSE = ",".join( targetSEs )
    if catalog is not None:
      replicateAndRegister.Catalog = catalog

    for lfn in lfnChunk:
      metaDict = metaDatas["Successful"][lfn]
      opFile = File()
      opFile.LFN = lfn
      opFile.Size = metaDict["Size"]

      if "Checksum" in metaDict:
        # # should check checksum type, now assuming Adler32 (metaDict["ChecksumType"] = 'AD'
        opFile.Checksum = metaDict["Checksum"]
        opFile.ChecksumType = "ADLER32"
      replicateAndRegister.addFile( opFile )

    request.addOperation( replicateAndRegister )

    putRequest = reqClient.putRequest( request )
    if not putRequest["OK"]:
      gLogger.error( "unable to put request '%s': %s" % ( request.RequestName, putRequest["Message"] ) )
      error = -1
      continue
    requestIDs.append( str( putRequest["Value"] ) )
    if not multiRequests:
      gLogger.always( "Request '%s' has been put to ReqDB for execution." % request.RequestName )

  if multiRequests:
    gLogger.always( "%d requests have been put to ReqDB for execution, with name %s_<num>" % ( count, requestName ) )
  if requestIDs:
示例#59
0
class RequestDBTests(unittest.TestCase):
    """
  .. class:: RequestDBTests
  unittest for RequestDB
  """

    def setUp(self):
        """ test case setup """
        self.request = Request({"RequestName": "test1", "JobID": 1})
        self.operation1 = Operation({"Type": "ReplicateAndRegister", "TargetSE": "CERN-USER"})
        self.file = File({"LFN": "/a/b/c", "ChecksumType": "ADLER32", "Checksum": "123456"})
        self.request.addOperation(self.operation1)
        self.operation1.addFile(self.file)
        self.operation2 = Operation()
        self.operation2.Type = "RemoveFile"
        self.operation2.addFile(File({"LFN": "/c/d/e"}))
        self.request.addOperation(self.operation2)

        # ## set some defaults
        gConfig.setOptionValue("DIRAC/Setup", "Test")
        gConfig.setOptionValue("/DIRAC/Setups/Test/RequestManagement", "Test")
        gConfig.setOptionValue("/Systems/RequestManagement/Test/Databases/ReqDB/Host", "localhost")
        gConfig.setOptionValue("/Systems/RequestManagement/Test/Databases/ReqDB/DBName", "ReqDB")
        gConfig.setOptionValue("/Systems/RequestManagement/Test/Databases/ReqDB/User", "Dirac")

        self.i = 1000

    def tearDown(self):
        """ test case tear down """
        del self.file
        del self.operation1
        del self.operation2
        del self.request

    def test01TableDesc(self):
        """ table description """
        tableDict = RequestDB.getTableMeta()
        self.assertEqual("Request" in tableDict, True)
        self.assertEqual("Operation" in tableDict, True)
        self.assertEqual("File" in tableDict, True)
        self.assertEqual(tableDict["Request"], Request.tableDesc())
        self.assertEqual(tableDict["Operation"], Operation.tableDesc())
        self.assertEqual(tableDict["File"], File.tableDesc())

    def test03RequestRW(self):
        """ db r/w requests """
        db = RequestDB()
        db._checkTables(True)

        # # empty DB at that stage
        ret = db.getDBSummary()
        self.assertEqual(ret, {"OK": True, "Value": {"Operation": {}, "Request": {}, "File": {}}})

        # # insert
        ret = db.putRequest(self.request)
        self.assertEqual(ret, {"OK": True, "Value": ""})

        # # get digest -> JSON
        ret = db.getDigest(self.request.RequestName)
        self.assertEqual(ret["OK"], True)
        self.assertEqual(bool(ret["Value"]), True)

        # # db summary
        ret = db.getDBSummary()
        self.assertEqual(
            ret,
            {
                "OK": True,
                "Value": {
                    "Operation": {"RemoveFile": {"Queued": 1L}, "ReplicateAndRegister": {"Waiting": 1L}},
                    "Request": {"Waiting": 1L},
                    "File": {"Waiting": 2L},
                },
            },
        )

        # # get request for jobs
        ret = db.getRequestNamesForJobs([1])
        self.assertEqual(ret["OK"], True)
        self.assertEqual(ret["Value"], {1: "test1"})

        # # read requests
        ret = db.readRequestsForJobs([1])
        self.assertEqual(ret["OK"], True)
        self.assertEqual(ret["Value"][1]["OK"], True)

        # # select
        ret = db.getRequest()
        self.assertEqual(ret["OK"], True)
        request = ret["Value"]
        self.assertEqual(isinstance(request, Request), True)

        # # summary
        ret = db.getDBSummary()
        self.assertEqual(
            ret,
            {
                "OK": True,
                "Value": {
                    "Operation": {"RemoveFile": {"Queued": 1L}, "ReplicateAndRegister": {"Waiting": 1L}},
                    "Request": {"Assigned": 1L},
                    "File": {"Waiting": 2L},
                },
            },
        )
        # # update
        ret = db.putRequest(request)
        self.assertEqual(ret, {"OK": True, "Value": ""})

        # # get summary again
        ret = db.getDBSummary()
        self.assertEqual(
            ret,
            {
                "OK": True,
                "Value": {
                    "Operation": {"RemoveFile": {"Queued": 1L}, "ReplicateAndRegister": {"Waiting": 1L}},
                    "Request": {"Waiting": 1L},
                    "File": {"Waiting": 2L},
                },
            },
        )

        # # delete
        ret = db.deleteRequest(self.request.RequestName)
        self.assertEqual(ret, {"OK": True, "Value": ""})

        # # should be empty now
        ret = db.getDBSummary()
        self.assertEqual(ret, {"OK": True, "Value": {"Operation": {}, "Request": {}, "File": {}}})

    def test04Stress(self):
        """ stress test """

        db = RequestDB()

        for i in range(self.i):
            request = Request({"RequestName": "test-%d" % i})
            op = Operation({"Type": "RemoveReplica", "TargetSE": "CERN-USER"})
            op += File({"LFN": "/lhcb/user/c/cibak/foo"})
            request += op
            put = db.putRequest(request)
            self.assertEqual(put["OK"], True, "put failed")

        for i in range(self.i):
            get = db.getRequest("test-%s" % i, False)
            if "Message" in get:
                print get["Message"]
            self.assertEqual(get["OK"], True, "get failed")

        for i in range(self.i):
            delete = db.deleteRequest("test-%s" % i)
            self.assertEqual(delete["OK"], True, "delete failed")

    def test05Scheduled(self):
        """ scheduled request r/w """

        db = RequestDB()

        req = Request({"RequestName": "FTSTest"})
        op = Operation({"Type": "ReplicateAndRegister", "TargetSE": "CERN-USER"})
        op += File({"LFN": "/a/b/c", "Status": "Scheduled", "Checksum": "123456", "ChecksumType": "ADLER32"})
        req += op

        put = db.putRequest(req)
        self.assertEqual(put["OK"], True, "putRequest failed")

        peek = db.peekRequest(req.RequestName)
        self.assertEqual(peek["OK"], True, "peek failed ")

        peek = peek["Value"]
        for op in peek:
            opId = op.OperationID

        getFTS = db.getScheduledRequest(opId)
        self.assertEqual(getFTS["OK"], True, "getScheduled failed")
        self.assertEqual(getFTS["Value"].RequestName, "FTSTest", "wrong request selected")

    def test06Dirty(self):
        """ dirty records """
        db = RequestDB()

        r = Request()
        r.RequestName = "dirty"

        op1 = Operation({"Type": "ReplicateAndRegister", "TargetSE": "CERN-USER"})
        op1 += File({"LFN": "/a/b/c/1", "Status": "Scheduled", "Checksum": "123456", "ChecksumType": "ADLER32"})

        op2 = Operation({"Type": "ReplicateAndRegister", "TargetSE": "CERN-USER"})
        op2 += File({"LFN": "/a/b/c/2", "Status": "Scheduled", "Checksum": "123456", "ChecksumType": "ADLER32"})

        op3 = Operation({"Type": "ReplicateAndRegister", "TargetSE": "CERN-USER"})
        op3 += File({"LFN": "/a/b/c/3", "Status": "Scheduled", "Checksum": "123456", "ChecksumType": "ADLER32"})

        r += op1
        r += op2
        r += op3

        put = db.putRequest(r)
        self.assertEqual(put["OK"], True, "1. putRequest failed: %s" % put.get("Message", ""))

        r = db.getRequest("dirty")
        self.assertEqual(r["OK"], True, "1. getRequest failed: %s" % r.get("Message", ""))
        r = r["Value"]

        del r[0]
        self.assertEqual(len(r), 2, "1. len wrong")

        put = db.putRequest(r)
        self.assertEqual(put["OK"], True, "2. putRequest failed: %s" % put.get("Message", ""))

        r = db.getRequest("dirty")
        self.assertEqual(r["OK"], True, "2. getRequest failed: %s" % r.get("Message", ""))

        r = r["Value"]
        self.assertEqual(len(r), 2, "2. len wrong")

        op4 = Operation({"Type": "ReplicateAndRegister", "TargetSE": "CERN-USER"})
        op4 += File({"LFN": "/a/b/c/4", "Status": "Scheduled", "Checksum": "123456", "ChecksumType": "ADLER32"})

        r[0] = op4
        put = db.putRequest(r)
        self.assertEqual(put["OK"], True, "3. putRequest failed: %s" % put.get("Message", ""))

        r = db.getRequest("dirty")
        self.assertEqual(r["OK"], True, "3. getRequest failed: %s" % r.get("Message", ""))
        r = r["Value"]

        self.assertEqual(len(r), 2, "3. len wrong")