Example #1
0
    def setUp(self):
        self.dra = DataRecoveryAgent(
            agentName="ILCTransformationSystem/DataRecoveryAgent",
            loadName="TestDRA")
        self.dra.transNoInput = ["MCGeneration"]
        self.dra.transWithInput = ["MCSimulation", "MCReconstruction"]
        self.dra.transformationTypes = [
            "MCGeneration", "MCSimulation", "MCReconstruction"
        ]

        self.dra.reqClient = Mock(
            name="reqMock",
            spec=DIRAC.RequestManagementSystem.Client.ReqClient.ReqClient)
        self.dra.tClient = Mock(name="transMock",
                                spec=DIRAC.TransformationSystem.Client.
                                TransformationClient.TransformationClient)
        self.dra.fcClient = Mock(
            name="fcMock",
            spec=DIRAC.Resources.Catalog.FileCatalogClient.FileCatalogClient)
        self.dra.jobMon = Mock(name="jobMonMock",
                               spec=DIRAC.WorkloadManagementSystem.Client.
                               JobMonitoringClient.JobMonitoringClient)
        self.dra.printEveryNJobs = 10
        self.dra.log = Mock(name="LogMock")
        self.dra.addressTo = "myself"
        self.dra.addressFrom = "me"
def main():
    PARAMS = Params()
    PARAMS.registerSwitches()
    Script.parseCommandLine(ignoreErrors=False)

    # Create Data Recovery Agent and run over single transformation.
    from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
    from DIRAC.TransformationSystem.Agent.DataRecoveryAgent import DataRecoveryAgent

    DRA = DataRecoveryAgent("Transformation/DataRecoveryAgent",
                            "Transformation/DataRecoveryAgent")
    DRA.jobStatus = ["Done", "Failed"]
    DRA.enabled = PARAMS.enabled
    TRANSFORMATION = TransformationClient().getTransformations(
        condDict={"TransformationID": PARAMS.transID})
    if not TRANSFORMATION["OK"]:
        gLogger.error("Failed to find transformation: %s" %
                      TRANSFORMATION["Message"])
        exit(1)
    if not TRANSFORMATION["Value"]:
        gLogger.error("Did not find any transformations")
        exit(1)
    TRANS_INFO_DICT = TRANSFORMATION["Value"][0]
    TRANS_INFO_DICT.pop("Body", None)
    gLogger.notice("Found transformation: %s" % TRANS_INFO_DICT)
    DRA.treatTransformation(PARAMS.transID, TRANS_INFO_DICT)
    exit(0)
def main():
  PARAMS = Params()
  PARAMS.registerSwitches()
  Script.parseCommandLine(ignoreErrors=False)

  # Create Data Recovery Agent and run over single transformation.
  from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
  from DIRAC.TransformationSystem.Agent.DataRecoveryAgent import DataRecoveryAgent
  DRA = DataRecoveryAgent('Transformation/DataRecoveryAgent', 'Transformation/DataRecoveryAgent')
  DRA.jobStatus = ['Done', 'Failed']
  DRA.enabled = PARAMS.enabled
  TRANSFORMATION = TransformationClient().getTransformations(condDict={'TransformationID': PARAMS.transID})
  if not TRANSFORMATION['OK']:
    gLogger.error('Failed to find transformation: %s' % TRANSFORMATION['Message'])
    exit(1)
  if not TRANSFORMATION['Value']:
    gLogger.error('Did not find any transformations')
    exit(1)
  TRANS_INFO_DICT = TRANSFORMATION['Value'][0]
  TRANS_INFO_DICT.pop('Body', None)
  gLogger.notice('Found transformation: %s' % TRANS_INFO_DICT)
  DRA.treatTransformation(PARAMS.transID, TRANS_INFO_DICT)
  exit(0)
Example #4
0
 def test_init(self):
     """test for DataRecoveryAgent initialisation...................................................."""
     res = DataRecoveryAgent(
         agentName="ILCTransformationSystem/DataRecoveryAgent",
         loadName="TestDRA")
     self.assertIsInstance(res, DataRecoveryAgent)
Example #5
0
class TestDRA(unittest.TestCase):
    """Test the DataRecoveryAgent"""

    dra = None

    @patch("DIRAC.Core.Base.AgentModule.PathFinder", new=Mock())
    @patch("DIRAC.ConfigurationSystem.Client.PathFinder.getSystemInstance",
           new=Mock())
    @patch("%s.ReqClient" % MODULE_NAME, new=Mock())
    def setUp(self):
        self.dra = DataRecoveryAgent(
            agentName="ILCTransformationSystem/DataRecoveryAgent",
            loadName="TestDRA")
        self.dra.transNoInput = ["MCGeneration"]
        self.dra.transWithInput = ["MCSimulation", "MCReconstruction"]
        self.dra.transformationTypes = [
            "MCGeneration", "MCSimulation", "MCReconstruction"
        ]

        self.dra.reqClient = Mock(
            name="reqMock",
            spec=DIRAC.RequestManagementSystem.Client.ReqClient.ReqClient)
        self.dra.tClient = Mock(name="transMock",
                                spec=DIRAC.TransformationSystem.Client.
                                TransformationClient.TransformationClient)
        self.dra.fcClient = Mock(
            name="fcMock",
            spec=DIRAC.Resources.Catalog.FileCatalogClient.FileCatalogClient)
        self.dra.jobMon = Mock(name="jobMonMock",
                               spec=DIRAC.WorkloadManagementSystem.Client.
                               JobMonitoringClient.JobMonitoringClient)
        self.dra.printEveryNJobs = 10
        self.dra.log = Mock(name="LogMock")
        self.dra.addressTo = "myself"
        self.dra.addressFrom = "me"

    def tearDown(self):
        pass

    def getTestMock(self, nameID=0, jobID=1234567):
        """create a JobInfo object with mocks"""
        from DIRAC.TransformationSystem.Utilities.JobInfo import JobInfo

        testJob = Mock(name="jobInfoMock_%s" % nameID, spec=JobInfo)
        testJob.jobID = jobID
        testJob.tType = "testType"
        testJob.otherTasks = []
        testJob.errorCounts = []
        testJob.status = "Done"
        testJob.transFileStatus = ["Assigned", "Assigned"]
        testJob.inputFileStatus = ["Exists", "Exists"]
        testJob.outputFiles = ["/my/stupid/file.lfn", "/my/stupid/file2.lfn"]
        testJob.outputFileStatus = ["Exists", "Exists"]
        testJob.inputFiles = ["inputfile.lfn", "inputfile2.lfn"]
        testJob.pendingRequest = False
        testJob.getTaskInfo = Mock()
        return testJob

    @patch("DIRAC.Core.Base.AgentModule.PathFinder", new=Mock())
    @patch("DIRAC.ConfigurationSystem.Client.PathFinder.getSystemInstance",
           new=Mock())
    @patch("%s.ReqClient" % MODULE_NAME, new=Mock())
    def test_init(self):
        """test for DataRecoveryAgent initialisation...................................................."""
        res = DataRecoveryAgent(
            agentName="ILCTransformationSystem/DataRecoveryAgent",
            loadName="TestDRA")
        self.assertIsInstance(res, DataRecoveryAgent)

    def test_beginExecution(self):
        """test for DataRecoveryAgent beginExecution...................................................."""
        theOps = Mock(name="OpsInstance")
        theOps.getValue.side_effect = [["MCGeneration"],
                                       ["MCReconstruction", "Merge"]]
        with patch(
                "DIRAC.TransformationSystem.Agent.DataRecoveryAgent.Operations",
                return_value=theOps):
            res = self.dra.beginExecution()
        assert isinstance(self.dra.transformationTypes, list)
        assert set(["MCGeneration", "MCReconstruction",
                    "Merge"]) == set(self.dra.transformationTypes)
        assert set(["MCGeneration"]) == set(self.dra.transNoInput)
        assert set(["MCReconstruction",
                    "Merge"]) == set(self.dra.transWithInput)
        self.assertFalse(self.dra.enabled)
        self.assertTrue(res["OK"])

    def test_getEligibleTransformations_success(self):
        """test for DataRecoveryAgent getEligibleTransformations success................................"""
        transInfoDict = dict(
            TransformationID=1234,
            TransformationName="TestProd12",
            Type="TestProd",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )
        self.dra.tClient.getTransformations = Mock(
            return_value=S_OK([transInfoDict]))
        res = self.dra.getEligibleTransformations(status="Active",
                                                  typeList=["TestProds"])
        self.assertTrue(res["OK"])
        self.assertIsInstance(res["Value"], dict)
        vals = res["Value"]
        self.assertIn("1234", vals)
        self.assertIsInstance(vals["1234"], dict)
        self.assertEqual(transInfoDict, vals["1234"])

    def test_getEligibleTransformations_failed(self):
        """test for DataRecoveryAgent getEligibleTransformations failure................................"""
        self.dra.tClient.getTransformations = Mock(
            return_value=S_ERROR("No can Do"))
        res = self.dra.getEligibleTransformations(status="Active",
                                                  typeList=["TestProds"])
        self.assertFalse(res["OK"])
        self.assertEqual("No can Do", res["Message"])

    def test_treatTransformation1(self):
        """test for DataRecoveryAgent treatTransformation success1.........................................."""
        getJobMock = Mock(name="getJobMOck")
        getJobMock.getJobs.return_value = (Mock(name="jobsMOck"), 50, 50)
        tinfoMock = Mock(name="infoMock", return_value=getJobMock)
        self.dra.checkAllJobs = Mock()
        # catch the printout to check path taken
        transInfoDict = dict(
            TransformationID=1234,
            TransformationName="TestProd12",
            Type="TestProd",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )
        with patch("%s.TransformationInfo" % MODULE_NAME, new=tinfoMock):
            self.dra.treatTransformation(1234, transInfoDict)  # returns None
        # check we start with the summary right away
        for _name, args, _kwargs in self.dra.log.notice.mock_calls:
            self.assertNotIn("Getting Tasks:", str(args))

    def test_treatTransformation2(self):
        """test for DataRecoveryAgent treatTransformation success2.........................................."""
        getJobMock = Mock(name="getJobMOck")
        getJobMock.getJobs.return_value = (Mock(name="jobsMock"), 50, 50)
        tinfoMock = Mock(name="infoMock", return_value=getJobMock)
        self.dra.checkAllJobs = Mock()
        # catch the printout to check path taken
        transInfoDict = dict(
            TransformationID=1234,
            TransformationName="TestProd12",
            Type="MCSimulation",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )
        with patch("%s.TransformationInfo" % MODULE_NAME, new=tinfoMock):
            self.dra.treatTransformation(1234, transInfoDict)  # returns None
        self.dra.log.notice.assert_any_call(
            MatchStringWith("Getting tasks..."))

    def test_treatTransformation3(self):
        """test for DataRecoveryAgent treatTransformation skip.............................................."""
        getJobMock = Mock(name="getJobMOck")
        getJobMock.getJobs.return_value = (Mock(name="jobsMock"), 50, 50)
        self.dra.checkAllJobs = Mock()
        self.dra.jobCache[1234] = (50, 50)
        # catch the printout to check path taken
        transInfoDict = dict(
            TransformationID=1234,
            TransformationName="TestProd12",
            Type="TestProd",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )

        with patch("%s.TransformationInfo" % MODULE_NAME,
                   autospec=True,
                   return_value=getJobMock):
            self.dra.treatTransformation(
                transID=1234, transInfoDict=transInfoDict)  # returns None
        self.dra.log.notice.assert_called_with(
            MatchStringWith("Skipping transformation 1234"))

    def test_checkJob(self):
        """test for DataRecoveryAgent checkJob No inputFiles............................................."""

        from DIRAC.TransformationSystem.Utilities.TransformationInfo import TransformationInfo

        tInfoMock = Mock(name="tInfoMock", spec=TransformationInfo)

        from DIRAC.TransformationSystem.Utilities.JobInfo import JobInfo

        # Test First option for MCGeneration
        tInfoMock.reset_mock()
        testJob = JobInfo(jobID=1234567,
                          status="Failed",
                          tID=123,
                          tType="MCGeneration")
        testJob.outputFiles = ["/my/stupid/file.lfn"]
        testJob.outputFileStatus = ["Exists"]

        self.dra.checkJob(testJob, tInfoMock)
        self.assertIn("setJobDone", tInfoMock.method_calls[0])
        self.assertEqual(self.dra.todo["NoInputFiles"][0]["Counter"], 1)
        self.assertEqual(self.dra.todo["NoInputFiles"][1]["Counter"], 0)

        # Test Second option for MCGeneration
        tInfoMock.reset_mock()
        testJob.status = "Done"
        testJob.outputFileStatus = ["Missing"]
        self.dra.checkJob(testJob, tInfoMock)
        self.assertIn("setJobFailed", tInfoMock.method_calls[0])
        self.assertEqual(self.dra.todo["NoInputFiles"][0]["Counter"], 1)
        self.assertEqual(self.dra.todo["NoInputFiles"][1]["Counter"], 1)

        # Test Second option for MCGeneration
        tInfoMock.reset_mock()
        testJob.status = "Done"
        testJob.outputFileStatus = ["Exists"]
        self.dra.checkJob(testJob, tInfoMock)
        self.assertEqual(tInfoMock.method_calls, [])
        self.assertEqual(self.dra.todo["NoInputFiles"][0]["Counter"], 1)
        self.assertEqual(self.dra.todo["NoInputFiles"][1]["Counter"], 1)

    @parameterized.expand([
        param(
            0,
            ["setJobDone", "setInputProcessed"],
            jStat="Failed",
            ifStat=["Exists"],
            ofStat=["Exists"],
            tFiStat=["Assigned"],
            others=True,
        ),
        param(
            1,
            ["setJobFailed"],
            ifStat=["Exists"],
            ofStat=["Missing"],
            others=True,
            ifProcessed=["/my/inputfile.lfn"],
        ),
        param(2, ["setJobFailed", "cleanOutputs"],
              ifStat=["Exists"],
              others=True,
              ifProcessed=["/my/inputfile.lfn"]),
        param(3, ["cleanOutputs", "setJobFailed", "setInputDeleted"],
              ifStat=["Missing"]),
        param(4, ["cleanOutputs", "setJobFailed"],
              tFiStat=["Deleted"],
              ifStat=["Missing"]),
        param(5, ["setJobDone", "setInputProcessed"],
              jStat="Failed",
              ifStat=["Exists"],
              tFiStat=["Assigned"]),
        param(6, ["setJobDone"],
              jStat="Failed",
              ifStat=["Exists"],
              tFiStat=["Processed"]),
        param(7, ["setInputProcessed"],
              jStat="Done",
              ifStat=["Exists"],
              tFiStat=["Assigned"]),
        param(
            8,
            ["setInputMaxReset"],
            jStat="Failed",
            ifStat=["Exists"],
            ofStat=["Missing"],
            tFiStat=["Assigned"],
            errorCount=[14],
        ),
        param(
            9,
            ["setInputUnused"],
            jStat="Failed",
            ifStat=["Exists"],
            ofStat=["Missing"],
            tFiStat=["Assigned"],
            errorCount=[2],
        ),
        param(
            10,
            ["setInputUnused", "setJobFailed"],
            jStat="Done",
            ifStat=["Exists"],
            ofStat=["Missing"],
            tFiStat=["Assigned"],
        ),
        param(
            11,
            ["cleanOutputs", "setInputUnused"],
            jStat="Failed",
            ifStat=["Exists"],
            ofStat=["Missing", "Exists"],
            tFiStat=["Assigned"],
        ),
        param(
            12,
            ["cleanOutputs", "setInputUnused", "setJobFailed"],
            jStat="Done",
            ifStat=["Exists"],
            ofStat=["Missing", "Exists"],
            tFiStat=["Assigned"],
        ),
        param(13, ["setJobFailed"],
              jStat="Done",
              ifStat=["Exists"],
              ofStat=["Missing", "Missing"],
              tFiStat=["Unused"]),
        param(14, [],
              jStat="Strange",
              ifStat=["Exists"],
              ofStat=["Exists"],
              tFiStat=["Processed"]),
        param(
            -1,
            [],
            jStat="Failed",
            ifStat=["Exists"],
            ofStat=["Missing", "Missing"],
            outFiles=["/my/stupid/file.lfn", "/my/stupid/file2.lfn"],
            tFiStat=["Processed"],
            others=True,
        ),
    ])
    def test_checkJob_others_(
        self,
        counter,
        infoCalls,
        jID=1234567,
        jStat="Done",
        others=False,
        inFiles=["/my/inputfile.lfn"],
        outFiles=["/my/stupid/file.lfn"],
        ifStat=[],
        ofStat=["Exists"],
        ifProcessed=[],
        tFiStat=["Processed"],
        errorCount=[],
    ):
        from DIRAC.TransformationSystem.Utilities.TransformationInfo import TransformationInfo
        from DIRAC.TransformationSystem.Utilities.JobInfo import JobInfo

        tInfoMock = Mock(name="tInfoMock", spec=TransformationInfo)
        testJob = JobInfo(jobID=jID,
                          status=jStat,
                          tID=123,
                          tType="MCSimulation")
        testJob.outputFiles = outFiles
        testJob.outputFileStatus = ofStat
        testJob.otherTasks = others
        testJob.inputFiles = inFiles
        testJob.inputFileStatus = ifStat
        testJob.transFileStatus = tFiStat
        testJob.errorCounts = errorCount
        self.dra.inputFilesProcessed = set(ifProcessed)
        self.dra.checkJob(testJob, tInfoMock)
        gLogger.notice("Testing counter", counter)
        gLogger.notice("Expecting calls", infoCalls)
        gLogger.notice("Called", tInfoMock.method_calls)
        assert len(infoCalls) == len(tInfoMock.method_calls)
        for index, infoCall in enumerate(infoCalls):
            self.assertIn(infoCall, tInfoMock.method_calls[index])
        for count in range(15):
            gLogger.notice("Checking Counter:", count)
            if count == counter:
                self.assertEqual(self.dra.todo["InputFiles"][count]["Counter"],
                                 1)
            else:
                self.assertEqual(self.dra.todo["InputFiles"][count]["Counter"],
                                 0)
        if 0 <= counter <= 2:
            assert set(testJob.inputFiles).issubset(
                self.dra.inputFilesProcessed)

    @parameterized.expand([
        param(["cleanOutputs", "setJobFailed"]),
        param([], jID=667, jStat="Failed", ofStat=["Missing"]),
        param([],
              jID=668,
              jStat="Failed",
              ofStat=["Missing"],
              inFiles=["some"]),
    ])
    def test_failHard(self,
                      infoCalls,
                      jID=666,
                      jStat="Done",
                      inFiles=None,
                      ofStat=["Exists"]):
        """Test the job.failHard function."""
        from DIRAC.TransformationSystem.Utilities.TransformationInfo import TransformationInfo
        from DIRAC.TransformationSystem.Utilities.JobInfo import JobInfo

        tInfoMock = Mock(name="tInfoMock", spec=TransformationInfo)
        tInfoMock.reset_mock()
        testJob = JobInfo(jobID=666,
                          status=jStat,
                          tID=123,
                          tType="MCSimulation")
        testJob.outputFiles = ["/my/stupid/file.lfn"]
        testJob.outputFileStatus = ofStat
        testJob.otherTasks = True
        testJob.inputFiles = inFiles
        testJob.inputFileExists = True
        testJob.fileStatus = "Processed"
        self.dra.inputFilesProcessed = set()
        self.dra._DataRecoveryAgent__failJobHard(testJob, tInfoMock)  # pylint: disable=protected-access, no-member
        gLogger.notice("Expecting calls", infoCalls)
        gLogger.notice("Called", tInfoMock.method_calls)
        assert len(infoCalls) == len(tInfoMock.method_calls)
        for index, infoCall in enumerate(infoCalls):
            self.assertIn(infoCall, tInfoMock.method_calls[index])
        if jStat == "Done":
            self.assertIn("Failing job %s" % jID, self.dra.notesToSend)
        else:
            self.assertNotIn("Failing job %s" % jID, self.dra.notesToSend)

    def test_notOnlyKeepers(self):
        """test for __notOnlyKeepers function"""

        funcToTest = self.dra._DataRecoveryAgent__notOnlyKeepers  # pylint: disable=protected-access, no-member
        self.assertTrue(funcToTest("MCGeneration"))

        self.dra.todo["InputFiles"][0]["Counter"] = 3  # keepers
        self.dra.todo["InputFiles"][3]["Counter"] = 0
        self.assertFalse(funcToTest("MCSimulation"))

        self.dra.todo["InputFiles"][0]["Counter"] = 3  # keepers
        self.dra.todo["InputFiles"][3]["Counter"] = 3
        self.assertTrue(funcToTest("MCSimulation"))

    def test_checkAllJob(self):
        """test for DataRecoveryAgent checkAllJobs ....................................................."""
        from DIRAC.TransformationSystem.Utilities.JobInfo import JobInfo

        # test with additional task dicts
        from DIRAC.TransformationSystem.Utilities.TransformationInfo import TransformationInfo

        tInfoMock = Mock(name="tInfoMock", spec=TransformationInfo)
        mockJobs = dict([(i, self.getTestMock()) for i in range(11)])
        mockJobs[2].pendingRequest = True
        mockJobs[3].getJobInformation = Mock(
            side_effect=(RuntimeError("ARGJob1"), None))
        mockJobs[4].getTaskInfo = Mock(side_effect=(TaskInfoException("ARG1"),
                                                    None))
        taskDict = True
        lfnTaskDict = True
        self.dra.checkAllJobs(mockJobs, tInfoMock, taskDict, lfnTaskDict)
        self.dra.log.error.assert_any_call(MatchStringWith("+++++ Exception"),
                                           "ARGJob1")
        self.dra.log.error.assert_any_call(
            MatchStringWith("Skip Task, due to TaskInfoException: ARG1"))
        self.dra.log.reset_mock()

        # test inputFile None
        mockJobs = dict([(i, self.getTestMock(nameID=i)) for i in range(5)])
        mockJobs[1].inputFiles = []
        mockJobs[1].getTaskInfo = Mock(
            side_effect=(TaskInfoException("NoInputFile"), None))
        mockJobs[1].tType = "MCSimulation"
        tInfoMock.reset_mock()
        self.dra.checkAllJobs(mockJobs, tInfoMock, taskDict, lfnTaskDict=True)
        self.dra.log.notice.assert_any_call(
            MatchStringWith("Failing job hard"))

    def test_checkAllJob_2(self):
        """Test where failJobHard fails (via cleanOutputs)."""
        from DIRAC.TransformationSystem.Utilities.TransformationInfo import TransformationInfo

        tInfoMock = Mock(name="tInfoMock", spec=TransformationInfo)
        mockJobs = dict([(i, self.getTestMock()) for i in range(5)])
        mockJobs[2].pendingRequest = True
        mockJobs[3].getTaskInfo = Mock(
            side_effect=(TaskInfoException("ARGJob3"), None))
        mockJobs[3].inputFiles = []
        mockJobs[3].tType = "MCReconstruction"
        self.dra._DataRecoveryAgent__failJobHard = Mock(
            side_effect=(RuntimeError("ARGJob4"), None), name="FJH")
        self.dra.checkAllJobs(mockJobs,
                              tInfoMock,
                              tasksDict=True,
                              lfnTaskDict=True)
        mockJobs[3].getTaskInfo.assert_called()
        self.dra._DataRecoveryAgent__failJobHard.assert_called()
        self.dra.log.error.assert_any_call(MatchStringWith("+++++ Exception"),
                                           "ARGJob4")
        self.dra.log.reset_mock()

    def test_execute(self):
        """test for DataRecoveryAgent execute .........................................................."""
        self.dra.treatTransformation = Mock()

        self.dra.transformationsToIgnore = [123, 456, 789]
        self.dra.jobCache = defaultdict(lambda: (0, 0))
        self.dra.jobCache[123] = (10, 10)
        self.dra.jobCache[124] = (10, 10)
        self.dra.jobCache[125] = (10, 10)

        # Eligible fails
        self.dra.log.reset_mock()
        self.dra.getEligibleTransformations = Mock(
            return_value=S_ERROR("outcast"))
        res = self.dra.execute()
        self.assertFalse(res["OK"])
        self.dra.log.error.assert_any_call(ANY, MatchStringWith("outcast"))
        self.assertEqual("Failure to get transformations", res["Message"])

        d123 = dict(
            TransformationID=123,
            TransformationName="TestProd123",
            Type="MCGeneration",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )
        d124 = dict(
            TransformationID=124,
            TransformationName="TestProd124",
            Type="MCGeneration",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )
        d125 = dict(
            TransformationID=125,
            TransformationName="TestProd125",
            Type="MCGeneration",
            AuthorDN="/some/cert/owner",
            AuthorGroup="Test_Prod",
        )

        # Eligible succeeds
        self.dra.log.reset_mock()
        self.dra.getEligibleTransformations = Mock(return_value=S_OK({
            123: d123,
            124: d124,
            125: d125
        }))
        res = self.dra.execute()
        self.assertTrue(res["OK"])
        self.dra.log.notice.assert_any_call(
            MatchStringWith(
                "Will ignore the following transformations: [123, 456, 789]"))
        self.dra.log.notice.assert_any_call(
            MatchStringWith("Ignoring Transformation: 123"))
        self.dra.log.notice.assert_any_call(
            MatchStringWith("Running over Transformation: 124"))

        # Notes To Send
        self.dra.log.reset_mock()
        self.dra.getEligibleTransformations = Mock(return_value=S_OK({
            123: d123,
            124: d124,
            125: d125
        }))
        self.dra.notesToSend = "Da hast du deine Karte"
        sendmailMock = Mock()
        sendmailMock.sendMail.return_value = S_OK("Nice Card")
        notificationMock = Mock(return_value=sendmailMock)
        with patch("%s.NotificationClient" % MODULE_NAME,
                   new=notificationMock):
            res = self.dra.execute()
        self.assertTrue(res["OK"])
        self.dra.log.notice.assert_any_call(
            MatchStringWith(
                "Will ignore the following transformations: [123, 456, 789]"))
        self.dra.log.notice.assert_any_call(
            MatchStringWith("Ignoring Transformation: 123"))
        self.dra.log.notice.assert_any_call(
            MatchStringWith("Running over Transformation: 124"))
        self.assertNotIn(124, self.dra.jobCache)  # was popped
        self.assertIn(125, self.dra.jobCache)  # was not popped
        gLogger.notice("JobCache: %s" % self.dra.jobCache)

        # sending notes fails
        self.dra.log.reset_mock()
        self.dra.notesToSend = "Da hast du deine Karte"
        sendmailMock = Mock()
        sendmailMock.sendMail.return_value = S_ERROR("No stamp")
        notificationMock = Mock(return_value=sendmailMock)
        with patch("%s.NotificationClient" % MODULE_NAME,
                   new=notificationMock):
            res = self.dra.execute()
        self.assertTrue(res["OK"])
        self.assertNotIn(124, self.dra.jobCache)  # was popped
        self.assertIn(125, self.dra.jobCache)  # was not popped
        self.dra.log.error.assert_any_call(
            MatchStringWith("Cannot send notification mail"), ANY)

        self.assertEqual("", self.dra.notesToSend)

    def test_printSummary(self):
        """test DataRecoveryAgent printSummary.........................................................."""
        self.dra.notesToSend = ""
        self.dra.printSummary()
        self.assertNotIn(
            " Other Tasks --> Keep                                    :     0",
            self.dra.notesToSend)

        self.dra.notesToSend = "Note This"
        self.dra.printSummary()

    def test_setPendingRequests_1(self):
        """Check the setPendingRequests function."""
        mockJobs = dict((i, self.getTestMock(jobID=i)) for i in range(11))
        reqMock = Mock()
        reqMock.Status = "Done"
        reqClient = Mock(
            name="reqMock",
            spec=DIRAC.RequestManagementSystem.Client.ReqClient.ReqClient)
        reqClient.readRequestsForJobs.return_value = S_OK({"Successful": {}})
        self.dra.reqClient = reqClient
        self.dra.setPendingRequests(mockJobs)
        for _index, mj in mockJobs.items():
            self.assertFalse(mj.pendingRequest)

    def test_setPendingRequests_2(self):
        """Check the setPendingRequests function."""
        mockJobs = dict((i, self.getTestMock(jobID=i)) for i in range(11))
        reqMock = Mock()
        reqMock.RequestID = 666
        reqClient = Mock(
            name="reqMock",
            spec=DIRAC.RequestManagementSystem.Client.ReqClient.ReqClient)
        reqClient.readRequestsForJobs.return_value = S_OK(
            {"Successful": {
                6: reqMock
            }})
        reqClient.getRequestStatus.return_value = {"Value": "Done"}
        self.dra.reqClient = reqClient
        self.dra.setPendingRequests(mockJobs)
        for _index, mj in mockJobs.items():
            self.assertFalse(mj.pendingRequest)
        reqClient.getRequestStatus.assert_called_once_with(666)

    def test_setPendingRequests_3(self):
        """Check the setPendingRequests function."""
        mockJobs = dict((i, self.getTestMock(jobID=i)) for i in range(11))
        reqMock = Mock()
        reqMock.RequestID = 555
        reqClient = Mock(
            name="reqMock",
            spec=DIRAC.RequestManagementSystem.Client.ReqClient.ReqClient)
        reqClient.readRequestsForJobs.return_value = S_OK(
            {"Successful": {
                5: reqMock
            }})
        reqClient.getRequestStatus.return_value = {"Value": "Pending"}
        self.dra.reqClient = reqClient
        self.dra.setPendingRequests(mockJobs)
        for index, mj in mockJobs.items():
            if index == 5:
                self.assertTrue(mj.pendingRequest)
            else:
                self.assertFalse(mj.pendingRequest)
        reqClient.getRequestStatus.assert_called_once_with(555)

    def test_setPendingRequests_Fail(self):
        """Check the setPendingRequests function."""
        mockJobs = dict((i, self.getTestMock(jobID=i)) for i in range(11))
        reqMock = Mock()
        reqMock.Status = "Done"
        reqClient = Mock(
            name="reqMock",
            spec=DIRAC.RequestManagementSystem.Client.ReqClient.ReqClient)
        reqClient.readRequestsForJobs.side_effect = (S_ERROR("Failure"),
                                                     S_OK({"Successful": {}}))
        self.dra.reqClient = reqClient
        self.dra.setPendingRequests(mockJobs)
        for _index, mj in mockJobs.items():
            self.assertFalse(mj.pendingRequest)

    def test_getLFNStatus(self):
        """Check the getLFNStatus function."""
        mockJobs = dict((i, self.getTestMock(jobID=i)) for i in range(11))
        self.dra.fcClient.exists.return_value = S_OK({
            "Successful": {
                "/my/stupid/file.lfn": True,
                "/my/stupid/file2.lfn": True
            }
        })
        lfnExistence = self.dra.getLFNStatus(mockJobs)
        self.assertEqual(lfnExistence, {
            "/my/stupid/file.lfn": True,
            "/my/stupid/file2.lfn": True
        })

        self.dra.fcClient.exists.side_effect = (
            S_ERROR("args"),
            S_OK({
                "Successful": {
                    "/my/stupid/file.lfn": True,
                    "/my/stupid/file2.lfn": True
                }
            }),
        )
        lfnExistence = self.dra.getLFNStatus(mockJobs)
        self.assertEqual(lfnExistence, {
            "/my/stupid/file.lfn": True,
            "/my/stupid/file2.lfn": True
        })
Example #6
0
                              self.setEnabled)
        Script.setUsageMessage('\n'.join([
            __doc__, '\nUsage:',
            '  %s [option|cfgfile] ...\n' % Script.scriptName
        ]))


if __name__ == '__main__':
    PARAMS = Params()
    PARAMS.registerSwitches()
    Script.parseCommandLine(ignoreErrors=False)

    # Create Data Recovery Agent and run over single transformation.
    from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
    from DIRAC.TransformationSystem.Agent.DataRecoveryAgent import DataRecoveryAgent
    DRA = DataRecoveryAgent('Transformation/DataRecoveryAgent',
                            'Transformation/DataRecoveryAgent')
    DRA.jobStatus = ['Done', 'Failed']
    DRA.enabled = PARAMS.enabled
    TRANSFORMATION = TransformationClient().getTransformations(
        condDict={'TransformationID': PARAMS.transID})
    if not TRANSFORMATION['OK']:
        gLogger.error('Failed to find transformation: %s' %
                      TRANSFORMATION['Message'])
        exit(1)
    if not TRANSFORMATION['Value']:
        gLogger.error('Did not find any transformations')
        exit(1)
    TRANS_INFO_DICT = TRANSFORMATION['Value'][0]
    TRANS_INFO_DICT.pop('Body', None)
    gLogger.notice('Found transformation: %s' % TRANS_INFO_DICT)
    DRA.treatTransformation(PARAMS.transID, TRANS_INFO_DICT)