diff --git a/Interfaces/API/NewInterface/Applications/KKMC.py b/Interfaces/API/NewInterface/Applications/KKMC.py new file mode 100644 index 0000000000000000000000000000000000000000..daeb1c4842f81a1084b934c3a09d2672be3dc148 --- /dev/null +++ b/Interfaces/API/NewInterface/Applications/KKMC.py @@ -0,0 +1,162 @@ +""" +KKMC: Interface to the KKMCee generator + +.. versionadded:: v29r2p5 + +Usage: + +>>> kkmc = KKMC () +>>> kkmc.setVersion('LCG_97a_FCC_4') +>>> kkmc.setConfigFile( '__path_to__/process.input' ) + +Usage: +>>> kkmc = KKMC () +>>> kkmc.setVersion('LCG_97a_FCC_4') +>>> kkmc.setEvtType('Mu') +>>> kkmc.setEnergy(91.2) +>>> kkmc.setNumberOfEvents(1000) +>>> kkmc.setOutputFile('kkmu_1000.LHE') + +""" + +import types +import os +import re + +from ILCDIRAC.Interfaces.API.NewInterface.LCApplication import LCApplication +from DIRAC import S_OK, S_ERROR, gLogger +from DIRAC.Core.Workflow.Parameter import Parameter +from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations + + +LOG = gLogger.getSubLogger(__name__) + +__RCSID__ = "$Id$" + + +class KKMC(LCApplication): + """ KKMC Application Class """ + + def __init__(self, paramdict=None): + self.randomSeed = -1 + self.eventType = '' + self.kkmcConfigFile = '' + self.seedFile = '' + super(KKMC, self).__init__(paramdict) + # Those 5 need to come after default constructor + self._modulename = 'KKMCAnalysis' + self._moduledescription = 'Module to run KKMC' + self.appname = 'kkmc' + self.datatype = 'GEN' + self._ops = Operations() + + def setEvtType(self, evttype): + """ Optional: Flavour to be generated (Mu|Tau|UDS|C|B|Hadrons). + + :param str evttype: Flavour to be generated + """ + self._checkArgs({'evttype': types.StringTypes}) + if self.addedtojob: + return self._reportError("Cannot modify this attribute once application has been added to Job") + self.eventType = evttype + return S_OK() + + def setConfigFile(self, kkmcConfigFilePath): + """ Set the KKMC options to be used + + :param str kkmcConfigFilePath: Path to the KKMC input file. + """ + self._checkArgs({'kkmcConfigFilePath': types.StringType}) + + # Chech if file exist + if not os.path.isfile(kkmcConfigFilePath): + return self._reportError('KKMC config file does not exist!') + + # Read file + self.kkmcConfigFile = open(kkmcConfigFilePath).read() + + return None + + def setSeedFile(self, seedFilePath): + """ Optional: set the file to be used for seeding (randomly generated, if missing) + + :param str seedFilePath: Path to the KKMC seed file. + """ + self._checkArgs({'seedFilePath': types.StringType}) + + # Chech if file exist + if not os.path.isfile(seedFilePath): + return self._reportError('The seed file does not exist! %s' % seedFilePath) + + # Read file + self.seedFile = open(seedFilePath).read() + + return None + + def _userjobmodules(self, stepdefinition): + res1 = self._setApplicationModuleAndParameters(stepdefinition) + res2 = self._setUserJobFinalization(stepdefinition) + if not res1["OK"] or not res2["OK"]: + return S_ERROR('userjobmodules failed') + return S_OK() + + def _prodjobmodules(self, stepdefinition): + res1 = self._setApplicationModuleAndParameters(stepdefinition) + res2 = self._setOutputComputeDataList(stepdefinition) + if not res1["OK"] or not res2["OK"]: + return S_ERROR('prodjobmodules failed') + return S_OK() + + def _checkConsistency(self, job=None): + """ + Check consistency of the KKMC application, this is called from the `Job` instance + + :param job: The instance of the job + :type job: ~ILCDIRAC.Interfaces.API.NewInterface.Job.Job + :returns: S_OK/S_ERROR + """ + + if not self.version: + return S_ERROR('No version found!') + + if self.kkmcConfigFile: + return S_OK() + + if not self.eventType and not self.energy and not self.numberOfEvents and not self.outputFile: + return S_ERROR('No config file set!') + if not self.eventType: + return S_ERROR('No event type set!') + if not self.energy: + return S_ERROR('No energy set!') + if not self.numberOfEvents: + return S_ERROR('No number of events set!') + if not self.outputFile: + return S_ERROR('No output file set!') + + return S_OK() + + def _applicationModule(self): + md1 = self._createModuleDefinition() + md1.addParameter(Parameter("debug", False, "bool", "", "", False, False, "debug mode")) + md1.addParameter(Parameter("kkmcConfigFile", '', "string", "", "", False, False, "KKMC steering options")) + md1.addParameter(Parameter("seedFile", '', "string", "", "", False, False, "Seed file for the generator")) + md1.addParameter( + Parameter( + "eventType", + '', + "string", + "", + "", + False, + False, + "Flavour to be generated (Mu|Tau|UDS|C|B|Hadrons)")) + return md1 + + def _applicationModuleValues(self, moduleinstance): + moduleinstance.setValue("debug", self.debug) + moduleinstance.setValue("kkmcConfigFile", self.kkmcConfigFile) + moduleinstance.setValue("seedFile", self.seedFile) + moduleinstance.setValue("eventType", self.eventType) + + def _checkWorkflowConsistency(self): + return self._checkRequiredApp() diff --git a/Interfaces/API/NewInterface/Applications/__init__.py b/Interfaces/API/NewInterface/Applications/__init__.py index b324b62fe3f67bd4a405b0e5ced05b152ada2970..6e07f93dd47314bbbc56b6888c78526e40ef660c 100644 --- a/Interfaces/API/NewInterface/Applications/__init__.py +++ b/Interfaces/API/NewInterface/Applications/__init__.py @@ -39,7 +39,9 @@ __all__ = ['GenericApplication', 'GetSRMFile', '_Root', 'RootScript', 'RootMacro 'Whizard', 'Pythia', 'PostGenSelection', 'StdhepCut', 'StdhepCutJava', 'Mokka', 'SLIC', 'OverlayInput', 'Marlin', 'LCSIM', 'SLICPandora', 'CheckCollections', 'SLCIOConcatenate', 'SLCIOSplit', 'StdHepSplit', - 'Tomato', 'CheckWNs', 'DDSim', 'Fcc', 'FccSw', 'FccAnalysis', 'Whizard2'] + 'Tomato', 'CheckWNs', 'DDSim', 'Fcc', 'FccSw', 'FccAnalysis', 'Whizard2', + 'KKMC', + ] from ILCDIRAC.Interfaces.API.NewInterface.Applications.GenericApplication import GenericApplication from ILCDIRAC.Interfaces.API.NewInterface.Applications.GetSRMFile import GetSRMFile @@ -68,3 +70,4 @@ from ILCDIRAC.Interfaces.API.NewInterface.Applications.Fcc import Fcc from ILCDIRAC.Interfaces.API.NewInterface.Applications.Fcc import FccSw from ILCDIRAC.Interfaces.API.NewInterface.Applications.Fcc import FccAnalysis from ILCDIRAC.Interfaces.API.NewInterface.Applications.Whizard2 import Whizard2 +from ILCDIRAC.Interfaces.API.NewInterface.Applications.KKMC import KKMC diff --git a/Interfaces/API/NewInterface/Tests/Test_KKMC.py b/Interfaces/API/NewInterface/Tests/Test_KKMC.py new file mode 100644 index 0000000000000000000000000000000000000000..002a2c5610c5df21fc1622221bdd8c418018fbfc --- /dev/null +++ b/Interfaces/API/NewInterface/Tests/Test_KKMC.py @@ -0,0 +1,176 @@ +#!/usr/local/env python +""" +Test KKMC module + +""" + +from __future__ import print_function +import linecache +import unittest +from mock import patch, MagicMock as Mock +from mock import mock_open +from mock import mock as mock_module + +from parameterized import parameterized + +from DIRAC import gLogger, S_OK, S_ERROR +from ILCDIRAC.Interfaces.API.NewInterface.Applications import KKMC +from ILCDIRAC.Tests.Utilities.GeneralUtils import assertEqualsImproved, assertDiracFailsWith, \ + assertDiracSucceeds + +__RCSID__ = "$Id$" + +MODULE_NAME = 'ILCDIRAC.Interfaces.API.NewInterface.Applications.KKMC' + +gLogger.setLevel("DEBUG") +gLogger.showHeaders(True) + +# pylint: disable=protected-access + + +class KKMCTestCase(unittest.TestCase): + """ Base class for the KKMC test cases + """ + + @classmethod + def setUpClass(cls): + """Load the Application file into the linecache to prevent exceptions when mocking the builtin open.""" + from ILCDIRAC.Interfaces.API.NewInterface import Application + for fName in [Application.__file__, mock_module.__file__]: + if fName.endswith(('.pyc', '.pyo')): + fName = fName[:-1] + linecache.getlines(fName) + + @classmethod + def tearDownClass(cls): + """Remove all entries from linecache because we mock builtin open.""" + linecache.clearcache() + + def setUp(self): + """set up the objects""" + self.kkmc = KKMC({}) + self.kkmc._ops = Mock(name='OpsMock') + + def test_setEvtType(self): + self.assertFalse(self.kkmc._errorDict) + self.kkmc.setEvtType('Mu') + self.assertFalse(self.kkmc._errorDict) + assertEqualsImproved(self.kkmc.eventType, 'Mu', self) + + @parameterized.expand([(15, False, '_checkArgs'), + ('Mu', True, 'setEvtType'), + ]) + def test_setEvtType_fail(self, evtType, addedToJob, errorMessage): + self.assertFalse(self.kkmc._errorDict) + self.kkmc.addedtojob = addedToJob + self.kkmc.setEvtType(evtType) + self.assertIn(errorMessage, self.kkmc._errorDict) + + @patch('os.path.isfile', new=Mock(return_value=True)) + @patch('__builtin__.open', mock_open(read_data='configFile content')) + def test_setConfigFile(self): + """Test setConfigFile.""" + self.assertFalse(self.kkmc._errorDict) + self.kkmc.setConfigFile('/some/path/configFile.input') + self.assertFalse(self.kkmc._errorDict) + assertEqualsImproved(self.kkmc.kkmcConfigFile, 'configFile content', self) + + def test_checkworkflow_app_missing(self): + self.kkmc._inputapp = ['some_depdency', 'unavailable_dependency_fail_on_this'] + self.kkmc._jobapps = ['myjobapp_1', 'some_dependency'] + assertDiracFailsWith(self.kkmc._checkWorkflowConsistency(), 'job order not correct', self) + + def test_checkworkflow_empty(self): + self.kkmc._inputapp = [] + self.kkmc._jobapps = [] + assertDiracSucceeds(self.kkmc._checkWorkflowConsistency(), self) + + def test_userjobmodules(self): + module_mock = Mock() + assertDiracSucceeds(self.kkmc._userjobmodules(module_mock), self) + + def test_prodjobmodules(self): + module_mock = Mock() + assertDiracSucceeds(self.kkmc._prodjobmodules(module_mock), self) + + def test_userjobmodules_fails(self): + with patch('%s._setUserJobFinalization' % MODULE_NAME, new=Mock(return_value=S_OK('something'))),\ + patch('%s._setApplicationModuleAndParameters' % MODULE_NAME, new=Mock(return_value=S_ERROR('some_test_err'))): + assertDiracFailsWith(self.kkmc._userjobmodules(None), + 'userjobmodules failed', self) + + def test_prodjobmodules_fails(self): + with patch('%s._setApplicationModuleAndParameters' % MODULE_NAME, new=Mock(return_value=S_OK('something'))), \ + patch('%s._setOutputComputeDataList' % MODULE_NAME, new=Mock(return_value=S_ERROR('some_other_test_err'))): + assertDiracFailsWith(self.kkmc._prodjobmodules(None), + 'prodjobmodules failed', self) + + def test_checkconsistency_configFile(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = 'kkmc_steer.input' + assertDiracSucceeds(self.kkmc._checkConsistency(Mock()), self) + + def test_checkconsistency_parameters(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = None + self.kkmc.eventType = 'Mu' + self.kkmc.energy = '91.2' + self.kkmc.numberOfEvents = '1000' + self.kkmc.outputFile = 'kkmu_1000.LHE' + assertDiracSucceeds(self.kkmc._checkConsistency(Mock()), self) + + def test_checkconsistency_noVersion(self): + self.kkmc.version = None + assertDiracFailsWith(self.kkmc._checkConsistency(Mock()), 'No version found!', self) + + def test_checkconsistency_noConfigFile(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = None + assertDiracFailsWith(self.kkmc._checkConsistency(Mock()), 'No config file set!', self) + + def test_checkconsistency_noEventType(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = None + self.kkmc.eventType = None + self.kkmc.energy = 91.2 + self.kkmc.numberOfEvents = 1000 + self.kkmc.outputFile = 'kkmu_1000.LHE' + assertDiracFailsWith(self.kkmc._checkConsistency(Mock()), 'No event type set!', self) + + def test_checkconsistency_noEnergy(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = None + self.kkmc.eventType = 'Mu' + self.kkmc.energy = None + self.kkmc.numberOfEvents = 1000 + self.kkmc.outputFile = 'kkmu_1000.LHE' + assertDiracFailsWith(self.kkmc._checkConsistency(Mock()), 'No energy set!', self) + + def test_checkconsistency_noNumberOfEvents(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = None + self.kkmc.eventType = 'Mu' + self.kkmc.energy = 91.2 + self.kkmc.numberOfEvents = None + self.kkmc.outputFile = 'kkmu_1000.LHE' + assertDiracFailsWith(self.kkmc._checkConsistency(Mock()), 'No number of events set!', self) + + def test_checkconsistency_noOutputFile(self): + self.kkmc.version = 'LCG_97a_FCC_4' + self.kkmc.kkmcConfigFile = None + self.kkmc.eventType = 'Mu' + self.kkmc.energy = 91.2 + self.kkmc.numberOfEvents = 1000 + self.kkmc.outputFile = None + assertDiracFailsWith(self.kkmc._checkConsistency(Mock()), 'No output file set!', self) + + +def runTests(): + """Runs our tests""" + suite = unittest.defaultTestLoader.loadTestsFromTestCase(KKMCTestCase) + testResult = unittest.TextTestRunner(verbosity=2).run(suite) + print(testResult) + + +if __name__ == '__main__': + runTests() diff --git a/Workflow/Modules/KKMCAnalysis.py b/Workflow/Modules/KKMCAnalysis.py new file mode 100644 index 0000000000000000000000000000000000000000..aa55d3fd68bb474c7539d9c59ad0da0cd2c973ed --- /dev/null +++ b/Workflow/Modules/KKMCAnalysis.py @@ -0,0 +1,159 @@ +''' +Run KKMC + +:author: Andrea Stano +:since: February 03, 2021 +''' + +import os + +from DIRAC.Core.Utilities.Subprocess import shellCall +from DIRAC.DataManagementSystem.Client.DataManager import DataManager +from DIRAC import S_OK, S_ERROR, gLogger +from ILCDIRAC.Workflow.Modules.ModuleBase import ModuleBase +from ILCDIRAC.Core.Utilities.CombinedSoftwareInstallation import getEnvironmentScript, extractTarball +from ILCDIRAC.Core.Utilities.resolvePathsAndNames import getProdFilename + +__RCSID__ = '$Id$' +LOG = gLogger.getSubLogger(__name__) + + +class KKMCAnalysis(ModuleBase): + """ + Specific Module to run a KKMC job. + """ + + def __init__(self): + super(KKMCAnalysis, self).__init__() + self.enable = True + self.STEP_NUMBER = '' + self.result = S_ERROR() + self.applicationName = 'kkmc' + self.startFrom = 0 + self.kkmcConfigFile = '' + self.seedFile = '' + self.eventType = '' + # self.eventstring = ['+++ Generating event'] + self.datMan = DataManager() + + def applicationSpecificInputs(self): + """ Resolve all input variables for the module here. + + :return: S_OK() + """ + + if "IS_PROD" in self.workflow_commons and self.workflow_commons["IS_PROD"]: + self.OutputFile = getProdFilename(self.OutputFile, + int(self.workflow_commons["PRODUCTION_ID"]), + int(self.workflow_commons["JOB_ID"]), + self.workflow_commons, + ) + + return S_OK('Parameters resolved') + + def runIt(self): + """ + Called by JobAgent + + Execute the following: + - get the environment variables that should have been set during installation + - prepare the steering file and command line parameters + - run KKMC on this steering file and catch the exit status + + :rtype: :func:`~DIRAC.Core.Utilities.ReturnValues.S_OK`, :func:`~DIRAC.Core.Utilities.ReturnValues.S_ERROR` + """ + self.result = S_OK() + if not self.platform: + self.result = S_ERROR('No ILC platform selected') + elif not self.applicationLog: + self.result = S_ERROR('No Log file provided') + if not self.result['OK']: + LOG.error("Failed to resolve input parameters:", self.result['Message']) + return self.result + + if not self.workflowStatus['OK'] or not self.stepStatus['OK']: + LOG.verbose('Workflow status = %s, step status = %s' % (self.workflowStatus['OK'], self.stepStatus['OK'])) + return S_OK('KKMC should not proceed as previous step did not end properly') + + # get the enviroment script + res = getEnvironmentScript( + self.platform, + self.applicationName, + self.applicationVersion, + S_ERROR("No init script provided in CVMFS!")) + if not res['OK']: + LOG.error("Could not obtain the environment script: ", res["Message"]) + return res + envScriptPath = res["Value"] + + CLIArguments = '' + + if self.kkmcConfigFile: + kkmcSteerName = 'KKMC_%s_Steer_%s.input' % (self.applicationVersion, self.STEP_NUMBER) + if os.path.exists(kkmcSteerName): + os.remove(kkmcSteerName) + + kkmcSteer = [] + kkmcSteer.append(self.kkmcConfigFile) + + with open(kkmcSteerName, 'w') as steerFile: + steerFile.write("\n".join(kkmcSteer)) + + CLIArguments += '--config %s ' % kkmcSteerName + else: + CLIArguments += '--flavour %s ' % self.eventType + CLIArguments += '--ecms %s ' % self.energy + CLIArguments += '--nevts %s ' % self.NumberOfEvents + CLIArguments += '--outfile %s ' % self.OutputFile + + if self.seedFile: + seedName = 'KKMC_%s_Seed_%s' % (self.applicationVersion, self.STEP_NUMBER) + if os.path.exists(seedName): + os.remove(seedName) + kkmcSeed = [] + kkmcSeed.append(self.seedFile) + + with open(seedName, 'w') as seedFile: + seedFile.write("\n".join(kkmcSeed)) + + CLIArguments += '--seedfile %s ' % seedName + + scriptName = 'kkmc_%s_Run_%s.sh' % (self.applicationVersion, self.STEP_NUMBER) + if os.path.exists(scriptName): + os.remove(scriptName) + script = [] + script.append('#!/bin/bash') + script.append('#####################################################################') + script.append('# Dynamically generated script to run a production or analysis job. #') + script.append('#####################################################################') + script.append('source %s' % envScriptPath) + script.append('echo =========') + script.append('env | sort >> localEnv.log') + script.append('echo kkmc:`which KKMCee`') + script.append('echo =========') + script.append('KKMCee %s' % CLIArguments) + script.append('declare -x appstatus=$?') + script.append('exit $appstatus') + + with open(scriptName, 'w') as scriptFile: + scriptFile.write("\n".join(script)) + + if os.path.exists(self.applicationLog): + os.remove(self.applicationLog) + + os.chmod(scriptName, 0o755) + comm = 'bash "./%s"' % scriptName + self.setApplicationStatus('KKMC %s step %s' % (self.applicationVersion, self.STEP_NUMBER)) + self.stdError = '' + self.result = shellCall(0, comm, callbackFunction=self.redirectLogOutput, bufferLimit=20971520) + resultTuple = self.result['Value'] + if not os.path.exists(self.applicationLog): + LOG.error("Something went terribly wrong, the log file is not present") + self.setApplicationStatus('%s failed to produce log file' % (self.applicationName)) + if not self.ignoreapperrors: + return S_ERROR('%s did not produce the expected log %s' % (self.applicationName, self.applicationLog)) + status = resultTuple[0] + + LOG.info("Status after the application execution is %s" % status) + + return self.finalStatusReport(status) diff --git a/Workflow/Modules/Test/Test_KKMCAnalysis.py b/Workflow/Modules/Test/Test_KKMCAnalysis.py new file mode 100644 index 0000000000000000000000000000000000000000..cdcbdc1669ccc2528a9b66137c90190f96a9a00e --- /dev/null +++ b/Workflow/Modules/Test/Test_KKMCAnalysis.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +"""Test the KKMC WorkflowModule""" + +from __future__ import print_function +import __builtin__ +import unittest +import os +import os.path +import shutil +import tempfile +from mock import patch, MagicMock as Mock, mock_open + +from parameterized import parameterized, param + +from DIRAC import gLogger, S_OK, S_ERROR +from ILCDIRAC.Workflow.Modules.KKMCAnalysis import KKMCAnalysis +from ILCDIRAC.Tests.Utilities.GeneralUtils import assertDiracSucceeds + +__RCSID__ = "$Id$" + +MODULE_NAME = 'ILCDIRAC.Workflow.Modules.KKMCAnalysis' +MODULEBASE_NAME = 'ILCDIRAC.Workflow.Modules.ModuleBase' +PROXYINFO_NAME = 'DIRAC.Core.Security.ProxyInfo' +# pylint: disable=too-many-public-methods, protected-access + +gLogger.setLevel("ERROR") +gLogger.showHeaders(True) + + +def cleanup(tempdir): + """ + Remove files after run + """ + try: + shutil.rmtree(tempdir) + except OSError: + pass + + +@patch("%s.getProxyInfoAsString" % MODULEBASE_NAME, new=Mock(return_value=S_OK())) +@patch("%s.getProxyInfoAsString" % PROXYINFO_NAME, new=Mock(return_value=S_OK())) +class TestKKMCAnalysis(unittest.TestCase): + """ test KKMCAnalysis """ + + def assertIn(self, *args, **kwargs): + """make this existing to placate pylint""" + return super(TestKKMCAnalysis, self).assertIn(*args, **kwargs) + + @patch("%s.getProxyInfoAsString" % MODULEBASE_NAME, new=Mock(return_value=S_OK())) + @patch("%s.getProxyInfoAsString" % PROXYINFO_NAME, new=Mock(return_value=S_OK())) + def setUp(self): + self.kkmc = KKMCAnalysis() + self.curdir = os.getcwd() + self.tempdir = tempfile.mkdtemp("", dir="./") + os.chdir(self.tempdir) + self.kkmc.ops = Mock() + + def tearDown(self): + os.chdir(self.curdir) + cleanup(self.tempdir) + + +class TestKKMCAnalysisRunit(TestKKMCAnalysis): + """ test KKMC runtIt """ + + def setUp(self): + super(TestKKMCAnalysisRunit, self).setUp() + self.logFileName = "localEnv.log" + with open(self.logFileName, "w") as logF: + logF.write("logged the logging logs") + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh"))) + @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0, "AllGood")))) + def test_KKMC_runIt_success(self): + """KKMC.runit .................................................................................""" + self.kkmc.platform = 'Windows' + self.kkmc.applicationLog = self.logFileName + # side effect for Script, userlibs, log, logAfter + with patch("os.path.exists", new=Mock(side_effect=[False, False, True, True])): + res = self.kkmc.runIt() + print(res) + assertDiracSucceeds(res, self) + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh"))) + @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0, "AllGood")))) + def test_KKMC_runIt_failure_LogFile(self): + """KKMC.runit failure with applicationLog......................................................""" + self.kkmc.platform = "Windows" + self.kkmc.applicationLog = self.logFileName + self.kkmc.ignoreapperrors = False + # side effect for Script, userlibs, log, logAfter + with patch("os.path.exists", new=Mock(side_effect=[False, False, False, False])): + res = self.kkmc.runIt() + self.assertIn("did not produce the expected log", res['Message']) + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh"))) + @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0, "AllGood")))) + def test_KKMC_runIt_failure_LogFile_ignore(self): + """KKMC.runit failure with applicationLog but ignore...........................................""" + self.kkmc.platform = "Windows" + self.kkmc.applicationLog = self.logFileName + self.kkmc.ignoreapperrors = True + # side effect for Script, userlibs, log, logAfter + with patch("os.path.exists", new=Mock(side_effect=[False, False, False, False])): + res = self.kkmc.runIt() + assertDiracSucceeds(res, self) + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh"))) + @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0, "AllGood")))) + def test_KKMC_runIt_failure_NoLogFile(self): + """KKMC.runit failure with applicationLog not set.............................................""" + self.kkmc.platform = "Windows" + self.kkmc.ignoreapperrors = True + # side effect for Script, userlibs, log, logAfter + with patch("os.path.exists", new=Mock(side_effect=[False, False, False, False])): + res = self.kkmc.runIt() + self.assertIn("No Log file provide", res['Message']) + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh"))) + @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0, "AllGood")))) + def test_KKMC_runIt_failure_NoPlatform(self): + """KKMC.runit failure with platform .........................................................""" + self.kkmc.applicationLog = self.logFileName + self.kkmc.ignoreapperrors = True + # side effect for Script, userlibs, log, logAfter + with patch("os.path.exists", new=Mock(side_effect=[False, False, False, False])): + res = self.kkmc.runIt() + self.assertIn("No ILC platform selected", res['Message']) + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh"))) + @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0, "AllGood")))) + def test_KKMC_runIt_success_LogAndScriptPresent(self): + """KKMC.runit success log and script exist...................................................""" + self.kkmc.platform = "Windows" + self.kkmc.applicationLog = self.logFileName + self.kkmc.ignoreapperrors = True + with open("kkmc__Run_.sh", "w") as scr: + scr.write("content") + with open("KKMC__Steer_.input", "w") as scr: + scr.write("content") + with open(self.logFileName, "w") as scr: + scr.write("content") + # side effect for Script, userlibs, log, logAfter + with patch("os.path.exists", new=Mock(side_effect=[True, True, False, True])): + res = self.kkmc.runIt() + assertDiracSucceeds(res, self) + + # @parameterized.expand([('NumberOfEvents', 100, 'n_events = 100'), + # ('OutputFile', 'test.slcio', 'sample_format = lcio'), + # ('OutputFile', 'test.ascii', 'sample_format = ascii'), + # ('OutputFile', 'test.stdhep', 'sample_format = stdhep'), + # ('randomSeed', '321', 'seed = 321'), + # param('KKMCRawSin', True, 'sample_format', pUnExpected=True), + # ]) + # @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_OK("setup.sh") ) ) + # @patch("%s.shellCall" % MODULE_NAME, new=Mock(return_value=S_OK((0,"AllGood")) ) ) + # def test_KKMC_runIt_success_configFile(self, pName, pValue, pExpected, pUnExpected=None): + # """kkmc.runit success with configFile.........................................................""" + # self.kkmc.platform = "Windows" + # self.kkmc.applicationLog = self.logFileName + # self.kkmc.kkmcConfigFile = "kkmc instructions" + # setattr(self.kkmc, pName, pValue) + # ## side effect for Steering1, Steering2, Script, userlib, log, logAfter + # with patch("os.path.exists", new=Mock(side_effect=[False, False, False, True] ) ): + # res = self.kkmc.runIt() + # assertDiracSucceeds( res, self ) + # self.assertEqual( self.kkmc.kkmcConfigFile , "kkmc instructions" ) + # self.assertIn( "kkmc instructions", open("KKMC__Steer_.input").read()) + # if not pUnExpected: + # self.assertIn(pExpected, open("KKMC__Steer_.input").read()) + # else: + # self.assertNotIn(pExpected, open("KKMC__Steer_.input").read()) + + @patch("%s.getEnvironmentScript" % MODULE_NAME, new=Mock(return_value=S_ERROR("missing setup.sh"))) + def test_KKMC_runIt_fail_env(self): + """kkmc.runit failed to get env................................................................""" + self.kkmc.platform = "Windows" + self.kkmc.applicationLog = self.logFileName + res = self.kkmc.runIt() + self.assertEqual(res['Message'], "missing setup.sh") + + +class TestKKMCAnalysisASI(TestKKMCAnalysis): + """kkmc.ApplicationSpecificInputs """ + + @patch.dict(os.environ, {"JOBID": "12345"}) + def test_KKMC_ASI_NoVariables(self): + """kkmc.applicationSpecificInputs: checks that no variables have been set after this call......""" + gLogger.setLevel("ERROR") + self.kkmc.workflow_commons = dict() + self.kkmc.applicationSpecificInputs() + self.assertFalse(self.kkmc.jobReport or self.kkmc.productionID) + + +def runTests(): + """Runs our tests""" + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestKKMCAnalysis) + suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestKKMCAnalysisRunit)) + suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestKKMCAnalysisASI)) + testResult = unittest.TextTestRunner(verbosity=2).run(suite) + print(testResult) + + +if __name__ == '__main__': + runTests()