###############################################################################
# (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration           #
#                                                                             #
# This software is distributed under the terms of the GNU General Public      #
# Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE".   #
#                                                                             #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization  #
# or submit itself to any jurisdiction.                                       #
###############################################################################
"""Test of the ProductionRequest and Production modules."""
# pylint: disable=line-too-long,invalid-name,protected-access,missing-docstring

import unittest
from unittest.mock import Mock, MagicMock

from LHCbDIRAC.BookkeepingSystem.Client.test.mock_BookkeepingClient import (
    BookkeepingClientFake,
    stepMC,
    stepMC2,
    stepStripp,
    mergeStep,
    mergeStepBHADRON,
    step1Dict,
    step2Dict,
    step124620Dict,
    step124621Dict,
    step125080,
    stepHistoMergingDict,
    mergeStepCALIBRA,
    mergeStepPIDMDST,
)
from LHCbDIRAC.ProductionManagementSystem.Client.ProductionRequest import ProductionRequest, _splitIntoProductionSteps
from LHCbDIRAC.ProductionManagementSystem.Client.Production import Production

prodsDict = {
    1: {
        "productionType": "DataStripping",
        "stepsInProd": [123, 456],
        "bkQuery": "Full",
        "removeInputsFlag": False,
        "tracking": 0,
        "outputSE": {"T1": "SE1"},
        "priority": 5,
        "cpu": 1000000,
        "outputFileMask": "",
        "outputFileStep": "",
        "input": [],
        "target": "",
        "groupSize": 1,
        "plugin": "ByRun",
        "inputDataPolicy": "download",
        "derivedProduction": 0,
        "transformationFamily": 0,
        "previousProd": None,
        "stepsInProd-ProdName": ["123['SDST']", "456['BHADRON.DST']"],
        "events": -1,
        "multicore": "False",
        "processors": (4, 4),
        "outputMode": "Any",
        "ancestorDepth": 0,
    },
    2: {
        "productionType": "Merge",
        "stepsInProd": [456],
        "bkQuery": "fromPreviousProd",
        "removeInputsFlag": True,
        "tracking": 1,
        "outputSE": {"T1": "SE1"},
        "priority": 8,
        "cpu": 300000,
        "outputFileMask": "",
        "outputFileStep": "",
        "input": [],
        "target": "",
        "groupSize": 1,
        "plugin": "BySize",
        "inputDataPolicy": "download",
        "derivedProduction": 0,
        "transformationFamily": 0,
        "previousProd": 1,
        "stepsInProd-ProdName": ["456['CALIBRATION.DST']"],
        "events": -1,
        "multicore": "False",
        "processors": (2, 2),
        "outputMode": "Local",
        "ancestorDepth": 0,
    },
    3: {
        "productionType": "Merge",
        "stepsInProd": [456],
        "bkQuery": "fromPreviousProd",
        "removeInputsFlag": True,
        "tracking": 1,
        "outputSE": {"T1": "SE1"},
        "priority": 9,
        "cpu": 10000,
        "outputFileMask": "",
        "outputFileStep": "",
        "input": [],
        "target": "",
        "groupSize": 2,
        "plugin": "BySize",
        "inputDataPolicy": "download",
        "derivedProduction": 0,
        "transformationFamily": 0,
        "previousProd": 1,
        "stepsInProd-ProdName": ["456['PID.MDST']"],
        "events": -1,
        "multicore": "True",
        "processors": (0, 2),
        "outputMode": "Any",
        "ancestorDepth": 0,
    },
    4: {
        "productionType": "Merge",
        "stepsInProd": [789],
        "bkQuery": "fromPreviousProd",
        "removeInputsFlag": True,
        "tracking": 1,
        "outputSE": {"T1": "SE1"},
        "priority": 9,
        "cpu": 1000,
        "outputFileMask": "",
        "outputFileStep": "",
        "input": [],
        "target": "",
        "groupSize": 3,
        "plugin": "BySize",
        "inputDataPolicy": "download",
        "derivedProduction": 0,
        "transformationFamily": 0,
        "previousProd": 1,
        "stepsInProd-ProdName": ["789['DAVINCIHIST', 'BRUNELHIST']"],
        "events": -1,
        "multicore": "True",
        "processors": (0, 0),
        "outputMode": "Any",
        "ancestorDepth": 0,
    },
}


class ClientTestCase(unittest.TestCase):
    """Base class for the Client test cases."""

    def setUp(self):
        self.bkClientMock = Mock()
        self.diracProdIn = Mock()
        self.diracProdIn.launchProduction.return_value = {"OK": True, "Value": 321}

        self.bkClientFake = BookkeepingClientFake()

        self.maxDiff = None


class ProductionRequestSuccess(ClientTestCase):
    def test__mcSpecialCase(self):
        # prepare the test case
        prod = Production()
        prod.setParameter("ProcessingType", "JDL", "Test", "ProductionGroupOrType")
        prod.addApplicationStep(stepDict=stepMC, modulesList=["GaudiApplication"])
        prod.addApplicationStep(stepDict=stepMC2, inputData="previousStep", modulesList=["GaudiApplication"])
        prod.priority = "1"
        prod.addFinalizationStep()
        prod.setFileMask("", "4")
        for par in prod.LHCbJob.workflow.parameters:
            if par.getName() == "Site":
                self.assertEqual(par.value, "ANY")
            if par.getName() == "outputDataFileMask":
                self.assertEqual(par.value, "")

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.tc = MagicMock()
        pr.opsH = MagicMock()
        pr.opsH.getValue.return_value = "testValue"
        prod.LHCbJob._siteSet = {"testValue"}

        pr._modifyAndLaunchMCXML(prod, {"tracking": 0})
        for par in prod.LHCbJob.workflow.parameters:
            if par.getName() == "Site":
                self.assertEqual(par.value, "testValue")
            if par.getName() == "numberOfEvents":
                self.assertEqual(par.value, "testValue")
            if par.getName() == "listoutput":
                self.assertTrue("gausshist" in dict(par.value).values())
            if par.getName() == "outputDataStep":
                self.assertEqual(par.value, "1;4")
            if par.getName() == "outputDataFileMask":
                self.assertEqual(par.value, "GAUSSHIST;DST")

        # # re-prepare the test case
        prod = Production()
        prod.setParameter("ProcessingType", "JDL", "Test", "ProductionGroupOrType")
        prod.addApplicationStep(stepDict=step1Dict, inputData="previousStep", modulesList=["GaudiApplication"])
        prod.addFinalizationStep()
        prod.setFileMask("", ["4"])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.tc = MagicMock()
        pr.opsH = MagicMock()
        pr.opsH.getValue.return_value = "testValue"
        prod.LHCbJob._siteSet = {"testValue"}

        # # re-run
        pr._mcSpecialCase(prod, {"tracking": 0})
        for par in prod.LHCbJob.workflow.parameters:
            if par.getName() == "Site":
                self.assertEqual(par.value, "ANY")
            if par.getName() == "listoutput":
                self.assertTrue("gausshist" not in dict(par.value).values())
            if par.getName() == "outputDataStep":
                self.assertEqual(par.value, "4")
            if par.getName() == "outputDataFileMask":
                self.assertEqual(par.value, "")
            if par.getName() == "Priority":
                self.assertEqual(par.value, "1")

        # And again re-prepare the test case
        prod = Production()
        prod.setParameter("ProcessingType", "JDL", "Test", "ProductionGroupOrType")
        prod.addApplicationStep(stepDict=step1Dict, inputData="previousStep", modulesList=["GaudiApplication"])
        prod.addFinalizationStep()
        prod.setFileMask("")

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.tc = MagicMock()
        pr.opsH = MagicMock()
        pr.opsH.getValue.return_value = "testValue"
        prod.LHCbJob._siteSet = {"testValue"}

        pr._mcSpecialCase(prod, {"tracking": 0})
        for par in prod.LHCbJob.workflow.parameters:
            if par.getName() == "Site":
                self.assertEqual(par.value, "ANY")
            if par.getName() == "listoutput":
                self.assertTrue("gausshist" not in dict(par.value).values())
            if par.getName() == "outputDataFileMask":
                self.assertEqual(par.value, "")
            if par.getName() == "Priority":
                self.assertEqual(par.value, "1")

    def test_resolveStepsSuccess(self):
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["123"]
        pr.outputVisFlag = [{"1": "N"}]
        pr.compressionLvl = ["LOW"]
        pr.resolveSteps()
        expected = dict(step1Dict)
        expected["OptionFiles"] = "optsFiles;$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py"
        self.assertEqual(pr.stepsListDict, [expected])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["125080"]  # this one already has a compression level
        pr.outputVisFlag = [{"1": "N"}]
        pr.resolveSteps()
        expected = dict(step125080)
        expectedOptionFiles = "$APPCONFIGOPTS/Gauss/Sim08-Beam4000GeV-mu100-2012-nu2.5.py;"
        expectedOptionFiles += "$DECFILESROOT/options/11102400.py;$LBPYTHIA8ROOT/options/Pythia8.py;"
        expectedOptionFiles += "$APPCONFIGOPTS/Gauss/G4PL_FTFP_BERT_EmNoCuts.py;"
        expected["OptionFiles"] = expectedOptionFiles
        self.assertEqual(pr.stepsListDict, [expected])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["125080"]  # this one already has a compression level
        pr.compressionLvl = ["LOW"]
        pr.outputVisFlag = [{"1": "N"}]
        pr.resolveSteps()
        expected = dict(step125080)
        self.assertEqual(pr.stepsListDict, [expected])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["125080"]  # this one already has a compression level
        pr.compressionLvl = ["HIGH"]  # this will replace it
        pr.outputVisFlag = [{"1": "N"}]
        pr.resolveSteps()
        expected = dict(step125080)
        expectedOptionFiles = "$APPCONFIGOPTS/Gauss/Sim08-Beam4000GeV-mu100-2012-nu2.5.py;"
        expectedOptionFiles += "$DECFILESROOT/options/11102400.py;"
        expectedOptionFiles += "$LBPYTHIA8ROOT/options/Pythia8.py;"
        expectedOptionFiles += "$APPCONFIGOPTS/Gauss/G4PL_FTFP_BERT_EmNoCuts.py;"
        expected["OptionFiles"] = expectedOptionFiles
        self.assertEqual(pr.stepsListDict, [expected])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["123", "456"]
        pr.compressionLvl = ["LOW", "HIGH"]
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}]
        expected1 = dict(step1Dict)
        expected1["OptionFiles"] = "optsFiles;$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py"
        expected2 = dict(step2Dict)
        expected2["OptionFiles"] = "optsFiles;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py"
        pr.resolveSteps()
        self.assertEqual(pr.stepsListDict, [expected1, expected2])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["123", "456", "789"]
        pr.compressionLvl = ["LOW", "HIGH", "HIGH"]
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}, {"3": "Y"}]
        expected1 = dict(step1Dict)
        expected1["OptionFiles"] = "optsFiles;$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py"
        expected2 = dict(step2Dict)
        expected2["OptionFiles"] = "optsFiles;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py"
        expected3 = dict(stepHistoMergingDict)
        expected3["OptionFiles"] = "optsFiles;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py"
        pr.resolveSteps()
        self.assertEqual(pr.stepsListDict, [expected1, expected2, expected3])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["124620", "124621"]
        pr.compressionLvl = ["LOW", "HIGH"]
        pr.outputVisFlag = [{"1": "N"}, {"2": "Y"}]
        expected1 = dict(step124620Dict)
        expected1["OptionFiles"] = "$APPCONFIGOPTS/Boole/Default.py;$APPCONFIGOPTS/Boole/DataType-2012.py;"
        expected2 = dict(step124621Dict)
        expected2["OptionFiles"] = "someBrunelOptions"
        pr.resolveSteps()
        self.assertEqual(pr.stepsListDict, [expected1, expected2])

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["123", "456", "", ""]
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}]
        pr.compressionLvl = ["LOW", "LOW", "HIGH", "HIGH"]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 123,
                    "StepName": "Stripping14-Stripping",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v2r2",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "optsFiles;$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py",
                    "Visible": "Yes",
                    "ExtraPackages": "eps",
                    "ProcessingPass": "procPass",
                    "OptionsFormat": "",
                    "SystemConfig": "",
                    "DDDB": "",
                    "CONDDB": "123456",
                    "DQTag": "",
                    "isMulticore": "N",
                    "prodStepID": "123['SDST']",
                    "mcTCK": "",
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesIn": ["SDST"],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
                {
                    "StepId": 456,
                    "StepName": "Merge",
                    "ApplicationName": "LHCb",
                    "ApplicationVersion": "v1r2",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "optsFiles;$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py",
                    "Visible": "Yes",
                    "ExtraPackages": "eps",
                    "ProcessingPass": "procPass",
                    "OptionsFormat": "",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "prodStepID": "456['BHADRON.DST', 'CALIBRATION.DST']",
                    "DDDB": "",
                    "CONDDB": "123456",
                    "DQTag": "",
                    "isMulticore": "N",
                    "mcTCK": "",
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesIn": ["BHADRON.DST", "CALIBRATION.DST"],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["123"]
        pr.outputVisFlag = [{"1": "N"}]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 123,
                    "StepName": "Stripping14-Stripping",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v2r2",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "optsFiles",
                    "Visible": "Yes",
                    "ExtraPackages": "eps",
                    "ProcessingPass": "procPass",
                    "OptionsFormat": "",
                    "SystemConfig": "",
                    "DDDB": "",
                    "CONDDB": "123456",
                    "DQTag": "",
                    "isMulticore": "N",
                    "prodStepID": "123['SDST']",
                    "mcTCK": "",
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesIn": ["SDST"],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["HIGH"]
        pr.stepsList = ["123"]
        pr.outputVisFlag = [{"1": "N"}]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 123,
                    "StepName": "Stripping14-Stripping",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v2r2",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "ProcessingPass": "procPass",
                    "OptionsFormat": "",
                    "SystemConfig": "",
                    "OptionFiles": "optsFiles;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py",
                    "Visible": "Yes",
                    "ExtraPackages": "eps",
                    "prodStepID": "123['SDST']",
                    "mcTCK": "",
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "DDDB": "",
                    "CONDDB": "123456",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["HIGH"]
        pr.outputVisFlag = [{"1": "Y"}]
        # pr.outputVisFlag = [{'Visibility':'N','FileType':'BHADRON.DST'},{'Visibility':'N','FileType':'CALIBRATION.DST'}]
        pr.stepsList = ["999"]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 999,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    # 'OptionFiles':'$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py',
                    # 'OptionFiles':'$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py',
                    "OptionFiles": "",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc5-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "999['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["HIGH"]
        pr.outputVisFlag = [{"1": "Y"}]
        pr.stepsList = ["998"]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 998,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    # 'OptionFiles':'$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py',
                    "OptionFiles": "$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "998['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["999"]
        pr.outputVisFlag = [{"1": "Y"}]
        pr.compressionLvl = [""] * 4
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 999,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    # 'OptionFiles':'$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py',
                    "OptionFiles": "",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc5-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "999['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["HIGH"]
        pr.outputVisFlag = [{"1": "Y"}]
        pr.stepsList = ["997"]
        pr.resolveSteps()
        optionFilesStep997 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;"
        optionFilesStep997 += "$APPCONFIGOPTS/Brunel/PbPb-GECs.py;$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py"
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 997,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep997,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "997['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["HIGH"]
        pr.outputVisFlag = [{"1": "Y"}]
        pr.stepsList = ["996"]
        pr.resolveSteps()
        optionFilesStep996 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;"
        optionFilesStep996 += "$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py;$APPCONFIGOPTS/Brunel/PbPb-GECs.py"
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 996,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep996,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "996['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = [""] * 4
        pr.outputVisFlag = [{"1": "Y"}]
        pr.stepsList = ["1098"]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 1098,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "$APPCONFIGOPTS/Brunel/DataType-2016.py;",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "1098['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["HIGH"]
        pr.outputVisFlag = [{"1": "Y"}]
        pr.specialOutputVisFlag = [{"1": {"BHADRON.DST": "Y"}}]
        pr.stepsList = ["1098"]
        pr.resolveSteps()
        optionFilesStep1098 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;"
        optionFilesStep1098 += "$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py;"
        optionFilesStep1098 += "$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py"
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 1098,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep1098,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "1098['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = [""]
        pr.outputVisFlag = [{"1": "Y"}]
        pr.specialOutputVisFlag = [{"1": {"BHADRON.DST": "Y"}}]
        pr.stepsList = ["1099"]
        pr.resolveSteps()
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 1099,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "$APPCONFIGOPTS/Brunel/DataType-2016.py;",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "1099['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "Y", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                }
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["", "HIGH", "LOW"]
        pr.outputVisFlag = [{"1": "N", "2": "N", "3": "N"}]
        pr.specialOutputVisFlag = [{"3": {"BHADRON.DST": "Y"}}]
        pr.stepsList = ["1098", "996", "997"]
        pr.resolveSteps()
        optionFilesStep996 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;"
        optionFilesStep996 += "$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py;"
        optionFilesStep996 += "$APPCONFIGOPTS/Brunel/PbPb-GECs.py"
        optionFilesStep997 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;"
        optionFilesStep997 += "$APPCONFIGOPTS/Brunel/PbPb-GECs.py;"
        optionFilesStep997 += "$APPCONFIGOPTS/Persistency/Compression-ZLIB-1.py"
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 1098,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "$APPCONFIGOPTS/Brunel/DataType-2016.py;",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "1098['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
                {
                    "StepId": 996,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep996,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "996['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
                {
                    "StepId": 997,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep997,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "997['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
            ],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.compressionLvl = ["", "HIGH"]
        pr.outputVisFlag = [{"1": "N", "2": "N", "3": "N"}]
        pr.specialOutputVisFlag = [{"2": {"BHADRON.DST": "Y"}}]
        pr.stepsList = ["1098", "996", "997"]
        pr.resolveSteps()
        optionFilesStep996 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;"
        optionFilesStep996 += "$APPCONFIGOPTS/Persistency/Compression-LZMA-4.py;$APPCONFIGOPTS/Brunel/PbPb-GECs.py"
        optionFilesStep997 = "$APPCONFIGOPTS/Brunel/DataType-2016.py;$APPCONFIGOPTS/Brunel/PbPb-GECs.py"
        self.assertEqual(
            pr.stepsListDict,
            [
                {
                    "StepId": 1098,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": "$APPCONFIGOPTS/Brunel/DataType-2016.py;",
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "1098['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
                {
                    "StepId": 996,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep996,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "996['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "Y", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
                {
                    "StepId": 997,
                    "StepName": "Stripping28",
                    "ApplicationName": "DaVinci",
                    "ApplicationVersion": "v41r3",
                    "ExtraOptions": "",
                    "EventTimeout": "",
                    "OptionFiles": optionFilesStep997,
                    "Visible": "Yes",
                    "Usable": "Yes",
                    "ProcessingPass": "Stripping28",
                    "SystemConfig": "x86_64-slc6-gcc49-opt",
                    "ExtraPackages": "AppConfig.v3r306",
                    "mcTCK": "",
                    "prodStepID": "997['SDST']",
                    "DDDB": "dddb-20150724",
                    "CONDDB": "cond-20161011",
                    "DQTag": "",
                    "isMulticore": "N",
                    "fileTypesIn": ["SDST"],
                    "visibilityFlag": [
                        {"Visible": "N", "FileType": "BHADRON.DST"},
                        {"Visible": "N", "FileType": "CALIBRATION.DST"},
                    ],
                    "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
                },
            ],
        )

    def test__determineOutputSEs(self):
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = ["123", "456"]
        pr.compressionLvl = ["LOW", "HIGH"]
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}]
        pr.resolveSteps()
        pr.outputSEs = ["SE1", "SE2"]
        pr.specialOutputSEs = [{}, {}]
        pr._determineOutputSEs()
        self.assertEqual(
            pr.outputSEsPerFileType,
            [{"CALIBRATION.DST": "SE1", "BHADRON.DST": "SE1"}, {"CALIBRATION.DST": "SE2", "BHADRON.DST": "SE2"}],
        )

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}]
        pr.stepsList = ["123", "456"]
        pr.compressionLvl = ["LOW", "HIGH"]
        pr.resolveSteps()
        pr.outputSEs = ["SE1", "SE2"]
        pr.specialOutputSEs = [{"CALIBRATION.DST": "SE3"}, {}]
        pr._determineOutputSEs()
        self.assertEqual(
            pr.outputSEsPerFileType,
            [{"CALIBRATION.DST": "SE3", "BHADRON.DST": "SE1"}, {"CALIBRATION.DST": "SE2", "BHADRON.DST": "SE2"}],
        )

    def test__applyOptionalCorrections(self):
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["DataStripping", "Merge"]
        pr.plugins = ["ByRun", "BySize"]
        pr.stepsListDict = [stepStripp, mergeStep]
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}]
        pr.stepsList = [123, 456]
        pr.stepsInProds = [[1], [2]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST"]
        pr.specialOutputSEs = [{}, {}]
        pr.priorities = [1, 4]
        pr.cpus = [10, 100]
        pr.groupSizes = [1, 2]
        pr.bkFileType = "TYPE"
        pr.removeInputsFlags = [False, True]
        pr.outputFileMasks = ["", "dst"]
        pr.outputFileSteps = ["", "2"]
        pr.inputs = [["aa"], []]
        pr.inputDataPolicies = ["dl", "pr"]
        pr.events = [-1, -1]
        pr.bkQueries = ["Full", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2"]
        pr.multicore = ["False", "True"]
        pr.processors = [(2, 4), (0, 0)]
        pr.outputModes = ["Local", "Any"]
        pr.ancestorDepths = [0, 1]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["DataStripping", "Merge", "Merge", "Merge"]
        pluginsExpected = ["ByRun", "BySize", "BySize", "BySize"]
        stepsListDictExpected = [stepStripp, mergeStepBHADRON, mergeStepCALIBRA, mergeStepPIDMDST]
        stepsInProdExpected = [[1], [2], [3], [4]]
        outputSEsExpected = ["Tier1-DST", "Tier1-M-DST", "Tier1-M-DST", "Tier1-M-DST"]
        specialOutputSEsExpected = [{}, {}, {}, {}]
        prioritiesExpected = [1, 4, 4, 4]
        cpusExpected = [10, 100, 100, 100]
        bkQueriesExpected = ["Full", "fromPreviousProd", "fromPreviousProd", "fromPreviousProd"]
        groupSizesExpected = [1, 2, 2, 2]
        previousProdsExpected = [None, 1, 1, 1]
        removeInputsFlagExpected = [False, True, True, True]
        outputFileMasksExpected = ["", "dst", "dst", "dst"]
        outputFileStepsExpected = ["", "2", "2", "2"]
        inputsExpected = [["aa"], [], [], []]
        inputDataPoliciesExpected = ["dl", "pr", "pr", "pr"]
        eventsExpected = [-1, -1, -1, -1]
        targetsExpected = ["Target1", "Target2", "Target2", "Target2"]
        multicoreExpected = ["False", "True", "True", "True"]
        processorsExpected = [(2, 4), (0, 0), (0, 0), (0, 0)]
        outputModeExpected = ["Local", "Any", "Any", "Any"]
        ancestorDepthsExpected = [0, 1, 1, 1]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.specialOutputSEs, specialOutputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["DataStripping", "Merge"]
        pr.plugins = ["ByRun", "ByRunFileTypeSizeWithFlush"]
        pr.stepsListDict = [stepStripp, mergeStep]
        pr.stepsList = [123, 456]
        pr.stepsInProds = [[1], [2]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST"]
        pr.specialOutputSEs = [{"Type1": "SE1"}, {}]
        pr.priorities = [1, 4]
        pr.cpus = [10, 100]
        pr.groupSizes = [1, 2]
        pr.bkFileType = ["Type1", "Type2"]
        pr.inputs = [[], ["aa"]]
        pr.removeInputsFlags = [False, True]
        pr.outputFileMasks = ["", "dst"]
        pr.outputFileSteps = ["", "2"]
        pr.inputDataPolicies = ["pr", "dl"]
        pr.events = [-1, -1]
        pr.bkQueries = ["Full", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2"]
        pr.multicore = ["False", "True"]
        pr.processors = [2, 0]
        pr.outputModes = ["Local", "Any"]
        pr.ancestorDepths = [0, 0]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["DataStripping", "Merge"]
        pluginsExpected = ["ByRun", "ByRunFileTypeSizeWithFlush"]
        stepsListDictExpected = [stepStripp, mergeStep]
        stepsInProdExpected = [[1], [2]]
        outputSEsExpected = ["Tier1-DST", "Tier1-M-DST"]
        specialOutputSEsExpected = [{"Type1": "SE1"}, {}]
        prioritiesExpected = [1, 4]
        cpusExpected = [10, 100]
        groupSizesExpected = [1, 2]
        bkQueriesExpected = ["Full", "fromPreviousProd"]
        previousProdsExpected = [None, 1]
        removeInputsFlagExpected = [False, True]
        outputFileMasksExpected = ["", "dst"]
        outputFileStepsExpected = ["", "2"]
        inputsExpected = [[], ["aa"]]
        inputDataPoliciesExpected = ["pr", "dl"]
        eventsExpected = [-1, -1]
        targetsExpected = ["Target1", "Target2"]
        multicoreExpected = ["False", "True"]
        processorsExpected = [2, 0]
        outputModeExpected = ["Local", "Any"]
        ancestorDepthsExpected = [0, 0]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.specialOutputSEs, specialOutputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["Merge", "Merge"]
        pr.plugins = ["BySize", "ByRunFileTypeSizeWithFlush"]
        pr.stepsListDict = [mergeStep, mergeStep]
        pr.stepsList = [456, 456]
        pr.stepsInProds = [[1], [2]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST"]
        pr.specialOutputSEs = [{"Type1": "SE1"}, {}]
        pr.priorities = [1, 4]
        pr.cpus = [10, 100]
        pr.groupSizes = [1, 2]
        pr.removeInputsFlags = [True, True]
        pr.outputFileMasks = ["", "dst"]
        pr.outputFileSteps = ["", "2"]
        pr.inputs = [[], ["aa"]]
        pr.inputDataPolicies = ["dl", "pr"]
        pr.events = [-1, -1]
        pr.bkQueries = ["fromPreviousProd", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2"]
        pr.multicore = ["False", "True"]
        pr.processors = [2, 0]
        pr.outputModes = ["Local", "Any"]
        pr.ancestorDepths = [1, 0]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["Merge", "Merge", "Merge", "Merge"]
        pluginsExpected = ["BySize", "BySize", "BySize", "ByRunFileTypeSizeWithFlush"]
        stepsListDictExpected = [mergeStepBHADRON, mergeStepCALIBRA, mergeStepPIDMDST, mergeStep]
        stepsInProdExpected = [[1], [2], [3], [4]]
        outputSEsExpected = ["Tier1-DST", "Tier1-DST", "Tier1-DST", "Tier1-M-DST"]
        specialOutputSEsExpected = [{"Type1": "SE1"}, {"Type1": "SE1"}, {"Type1": "SE1"}, {}]
        prioritiesExpected = [1, 1, 1, 4]
        cpusExpected = [10, 10, 10, 100]
        groupSizesExpected = [1, 1, 1, 2]
        bkQueriesExpected = ["fromPreviousProd", "fromPreviousProd", "fromPreviousProd", "fromPreviousProd"]
        previousProdsExpected = [None, None, None, 1]
        removeInputsFlagExpected = [True, True, True, True]
        outputFileMasksExpected = ["", "", "", "dst"]
        outputFileStepsExpected = ["", "", "", "2"]
        inputsExpected = [[], [], [], ["aa"]]
        inputDataPoliciesExpected = ["dl", "dl", "dl", "pr"]
        eventsExpected = [-1, -1, -1, -1]
        targetsExpected = ["Target1", "Target1", "Target1", "Target2"]
        multicoreExpected = ["False", "False", "False", "True"]
        processorsExpected = [2, 2, 2, 0]
        outputModeExpected = ["Local", "Local", "Local", "Any"]
        ancestorDepthsExpected = [1, 1, 1, 0]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.specialOutputSEs, specialOutputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["DataStripping"]
        pr.plugins = ["ByRun"]
        pr.stepsListDict = [stepStripp, mergeStep]
        pr.stepsList = [123]
        pr.stepsInProds = [[1, 2]]
        pr.priorities = [1]
        pr.outputSEs = ["Tier1-DST"]
        pr.cpus = [10]
        pr.groupSizes = [1]
        pr.bkFileType = "TYPE"
        pr.removeInputsFlags = [False]
        pr.outputFileMasks = [""]
        pr.outputFileSteps = ["2"]
        pr.inputs = [[]]
        pr.inputDataPolicies = [""]
        pr.events = [-1]
        pr.bkQueries = ["Full"]
        pr.targets = ["Target1"]
        pr.multicore = ["False"]
        pr.processors = [2]
        pr.outputModes = ["Local"]
        pr.ancestorDepths = [1]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["DataStripping"]
        pluginsExpected = ["ByRun"]
        stepsListDictExpected = [stepStripp, mergeStep]
        stepsInProdExpected = [[1, 2]]
        outputSEsExpected = ["Tier1-DST"]
        prioritiesExpected = [1]
        cpusExpected = [10]
        groupSizesExpected = [1]
        bkQueriesExpected = ["Full"]
        previousProdsExpected = [None]
        removeInputsFlagExpected = [False]
        outputFileMasksExpected = [""]
        outputFileStepsExpected = ["2"]
        inputsExpected = [[]]
        inputDataPoliciesExpected = [""]
        eventsExpected = [-1]
        targetsExpected = ["Target1"]
        multicoreExpected = ["False"]
        processorsExpected = [2]
        outputModeExpected = ["Local"]
        ancestorDepthsExpected = [1]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["DataStripping", "Merge", "Merge"]
        pr.plugins = ["ByRun", "BySize", "ByRunFileTypeSizeWithFlush"]
        pr.stepsListDict = [stepStripp, mergeStep, mergeStep]
        pr.stepsList = [123, 456, 456]
        pr.stepsInProds = [[1], [2], [3]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST", "Tier1-M-DST"]
        pr.priorities = [1, 4, 5]
        pr.cpus = [10, 100, 1000]
        pr.groupSizes = [1, 2, 3]
        pr.bkFileType = "TYPE"
        pr.removeInputsFlags = [False, True, True]
        pr.outputFileMasks = ["", "dst", ""]
        pr.outputFileSteps = ["", "2", ""]
        pr.inputs = [[], ["aa"], ["bb"]]
        pr.inputDataPolicies = ["", "dl", "pr"]
        pr.bkQueries = ["Full", "fromPreviousProd", "fromPreviousProd"]
        pr.events = [-1, -1, -1]
        pr.targets = ["Target1", "Target2", "Target3"]
        pr.multicore = ["False", "True", "False"]
        pr.processors = [2, 0, 4]
        pr.outputModes = ["Local", "Any", "Any"]
        pr.ancestorDepths = [1, 2, 3]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["DataStripping", "Merge", "Merge", "Merge", "Merge"]
        pluginsExpected = ["ByRun", "BySize", "BySize", "BySize", "ByRunFileTypeSizeWithFlush"]
        stepsListDictExpected = [stepStripp, mergeStepBHADRON, mergeStepCALIBRA, mergeStepPIDMDST, mergeStep]
        stepsInProdExpected = [[1], [2], [3], [4], [5]]
        outputSEsExpected = ["Tier1-DST", "Tier1-M-DST", "Tier1-M-DST", "Tier1-M-DST", "Tier1-M-DST"]
        prioritiesExpected = [1, 4, 4, 4, 5]
        groupSizesExpected = [1, 2, 2, 2, 3]
        cpusExpected = [10, 100, 100, 100, 1000]
        bkQueriesExpected = ["Full", "fromPreviousProd", "fromPreviousProd", "fromPreviousProd", "fromPreviousProd"]
        previousProdsExpected = [None, 1, 1, 1, 2]
        removeInputsFlagExpected = [False, True, True, True, True]
        outputFileMasksExpected = ["", "dst", "dst", "dst", ""]
        outputFileStepsExpected = ["", "2", "2", "2", ""]
        inputsExpected = [[], ["aa"], ["aa"], ["aa"], ["bb"]]
        inputDataPoliciesExpected = ["", "dl", "dl", "dl", "pr"]
        eventsExpected = [-1, -1, -1, -1, -1]
        targetsExpected = ["Target1", "Target2", "Target2", "Target2", "Target3"]
        multicoreExpected = ["False", "True", "True", "True", "False"]
        processorsExpected = [2, 0, 0, 0, 4]
        outputModeExpected = ["Local", "Any", "Any", "Any", "Any"]
        ancestorDepthsExpected = [1, 2, 2, 2, 3]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["DataStripping", "Merge"]
        pr.plugins = ["ByRun", "BySize"]
        pr.stepsListDict = [stepStripp, mergeStep]
        pr.stepsList = [123, 456]
        pr.stepsInProds = [[3], [4]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST"]
        pr.priorities = [1, 4]
        pr.cpus = [10, 100]
        pr.groupSizes = [1, 2]
        pr.bkFileType = "TYPE"
        pr.removeInputsFlags = [False, True]
        pr.outputFileMasks = ["", "dst"]
        pr.outputFileSteps = ["", "2"]
        pr.inputs = [[], []]
        pr.inputDataPolicies = ["", "dl"]
        pr.events = [-1, -1]
        pr.bkQueries = ["Full", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2"]
        pr.multicore = ["False", "True"]
        pr.processors = [2, 0]
        pr.outputModes = ["Local", "Any"]
        pr.ancestorDepths = [1, 0]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["DataStripping", "Merge", "Merge", "Merge"]
        pluginsExpected = ["ByRun", "BySize", "BySize", "BySize"]
        stepsListDictExpected = [stepStripp, mergeStepBHADRON, mergeStepCALIBRA, mergeStepPIDMDST]
        stepsInProdExpected = [[3], [4], [5], [6]]
        outputSEsExpected = ["Tier1-DST", "Tier1-M-DST", "Tier1-M-DST", "Tier1-M-DST"]
        prioritiesExpected = [1, 4, 4, 4]
        cpusExpected = [10, 100, 100, 100]
        groupSizesExpected = [1, 2, 2, 2]
        bkQueriesExpected = ["Full", "fromPreviousProd", "fromPreviousProd", "fromPreviousProd"]
        previousProdsExpected = [None, 1, 1, 1]
        removeInputsFlagExpected = [False, True, True, True]
        outputFileMasksExpected = ["", "dst", "dst", "dst"]
        outputFileStepsExpected = ["", "2", "2", "2"]
        inputsExpected = [[], [], [], []]
        inputDataPoliciesExpected = ["", "dl", "dl", "dl"]
        eventsExpected = [-1, -1, -1, -1]
        targetsExpected = ["Target1", "Target2", "Target2", "Target2"]
        multicoreExpected = ["False", "True", "True", "True"]
        processorsExpected = [2, 0, 0, 0]
        outputModeExpected = ["Local", "Any", "Any", "Any"]
        ancestorDepthsExpected = [1, 0, 0, 0]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["DataStripping"]
        pr.plugins = ["ByRun"]
        pr.stepsListDict = [stepStripp, mergeStep]
        pr.stepsList = [123, 456]
        pr.stepsInProds = [[3, 4]]
        pr.priorities = [1]
        pr.outputSEs = ["Tier1-DST"]
        pr.cpus = [10]
        pr.groupSizes = [1]
        pr.removeInputsFlags = [False]
        pr.outputFileMasks = ["dst"]
        pr.outputFileSteps = ["2"]
        pr.bkFileType = "TYPE"
        pr.inputs = [[]]
        pr.inputDataPolicies = ["dl"]
        pr.events = [-1]
        pr.bkQueries = ["Full"]
        pr.targets = ["Target1"]
        pr.multicore = ["False"]
        pr.processors = [2]
        pr.outputModes = ["Local"]
        pr.ancestorDepths = [1]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["DataStripping"]
        pluginsExpected = ["ByRun"]
        stepsListDictExpected = [stepStripp, mergeStep]
        stepsInProdExpected = [[3, 4]]
        outputSEsExpected = ["Tier1-DST"]
        prioritiesExpected = [1]
        cpusExpected = [10]
        groupSizesExpected = [1]
        bkQueriesExpected = ["Full"]
        previousProdsExpected = [None]
        removeInputsFlagExpected = [False]
        outputFileMasksExpected = ["dst"]
        outputFileStepsExpected = ["2"]
        inputsExpected = [[]]
        inputDataPoliciesExpected = ["dl"]
        eventsExpected = [-1]
        targetsExpected = ["Target1"]
        multicoreExpected = ["False"]
        processorsExpected = [2]
        outputModeExpected = ["Local"]
        ancestorDepthsExpected = [1]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["Merge", "Merge"]
        pr.plugins = ["BySize", "ByRunFileTypeSizeWithFlush"]
        pr.stepsListDict = [mergeStep, mergeStep]
        pr.stepsList = [456, 456]
        pr.stepsInProds = [[3], [4]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST"]
        pr.priorities = [1, 4]
        pr.cpus = [10, 100]
        pr.groupSizes = [1, 2]
        pr.removeInputsFlags = [True, True]
        pr.outputFileMasks = ["", "dst"]
        pr.outputFileSteps = ["", "2"]
        pr.inputs = [["aa"], ["bb"]]
        pr.inputDataPolicies = ["dl", "pr"]
        pr.events = [-1, -1]
        pr.bkQueries = ["Full", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2"]
        pr.multicore = ["False", "True"]
        pr.processors = [2, 0]
        pr.outputModes = ["Local", "Any"]
        pr.ancestorDepths = [1, 0]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["Merge", "Merge", "Merge", "Merge"]
        pluginsExpected = ["BySize", "BySize", "BySize", "ByRunFileTypeSizeWithFlush"]
        stepsListDictExpected = [mergeStepBHADRON, mergeStepCALIBRA, mergeStepPIDMDST, mergeStep]
        stepsInProdExpected = [[3], [4], [5], [6]]
        outputSEsExpected = ["Tier1-DST", "Tier1-DST", "Tier1-DST", "Tier1-M-DST"]
        prioritiesExpected = [1, 1, 1, 4]
        cpusExpected = [10, 10, 10, 100]
        groupSizesExpected = [1, 1, 1, 2]
        bkQueriesExpected = ["Full", "Full", "Full", "fromPreviousProd"]
        previousProdsExpected = [None, None, None, 1]
        removeInputsFlagExpected = [True, True, True, True]
        outputFileMasksExpected = ["", "", "", "dst"]
        outputFileStepsExpected = ["", "", "", "2"]
        inputsExpected = [["aa"], ["aa"], ["aa"], ["bb"]]
        inputDataPoliciesExpected = ["dl", "dl", "dl", "pr"]
        eventsExpected = [-1, -1, -1, -1]
        targetsExpected = ["Target1", "Target1", "Target1", "Target2"]
        multicoreExpected = ["False", "False", "False", "True"]
        processorsExpected = [2, 2, 2, 0]
        outputModeExpected = ["Local", "Local", "Local", "Any"]
        ancestorDepthsExpected = [1, 1, 1, 0]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["MCSimulation", "Merge"]
        pr.plugins = ["", "ByRunFileTypeSizeWithFlush"]
        pr.stepsListDict = [stepMC, mergeStep]
        pr.stepsList = [123, 456]
        pr.stepsInProds = [[1], [2]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST"]
        pr.priorities = [1, 4]
        pr.cpus = [10, 100]
        pr.groupSizes = [1, 2]
        pr.removeInputsFlags = [False, True]
        pr.outputFileMasks = ["", "dst"]
        pr.outputFileSteps = ["", "2"]
        pr.inputs = [[], []]
        pr.inputDataPolicies = ["", "dl"]
        pr.events = [100, -1]
        pr.bkQueries = ["", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2"]
        pr.multicore = ["False", "True"]
        pr.processors = [2, 0]
        pr.outputModes = ["Local", "Any"]
        pr.ancestorDepths = [1, 0]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["MCSimulation", "Merge"]
        pluginsExpected = ["", "ByRunFileTypeSizeWithFlush"]
        stepsListDictExpected = [stepMC, mergeStep]
        stepsInProdExpected = [[1], [2]]
        outputSEsExpected = ["Tier1-DST", "Tier1-M-DST"]
        prioritiesExpected = [1, 4]
        cpusExpected = [10, 100]
        groupSizesExpected = [1, 2]
        bkQueriesExpected = ["", "fromPreviousProd"]
        previousProdsExpected = [None, 1]
        removeInputsFlagExpected = [False, True]
        outputFileMasksExpected = ["", "dst"]
        outputFileStepsExpected = ["", "2"]
        inputsExpected = [[], []]
        inputDataPoliciesExpected = ["", "dl"]
        eventsExpected = [100, -1]
        targetsExpected = ["Target1", "Target2"]
        multicoreExpected = ["False", "True"]
        processorsExpected = [2, 0]
        outputModeExpected = ["Local", "Any"]
        ancestorDepthsExpected = [1, 0]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.prodsTypeList = ["MCSimulation", "Merge", "Merge"]
        pr.plugins = ["", "ByRunFileTypeSizeWithFlush", "RootMerging"]
        pr.stepsListDict = [stepMC, mergeStep, stepHistoMergingDict]
        pr.stepsList = [123, 456, 789]
        pr.stepsInProds = [[1], [2], [3]]
        pr.outputSEs = ["Tier1-DST", "Tier1-M-DST", "Tier1-M-DST"]
        pr.priorities = [1, 4, 5]
        pr.cpus = [10, 100, 100]
        pr.groupSizes = [1, 2, 3]
        pr.removeInputsFlags = [False, True, True]
        pr.outputFileMasks = ["", "dst", "root"]
        pr.outputFileSteps = ["", "2", "3"]
        pr.inputs = [[], [], []]
        pr.inputDataPolicies = ["", "dl", "dl"]
        pr.events = [100, -1, -1]
        pr.bkQueries = ["", "fromPreviousProd", "fromPreviousProd"]
        pr.targets = ["Target1", "Target2", "T3"]
        pr.multicore = ["False", "True", "True"]
        pr.processors = [2, 0, 0]
        pr.outputModes = ["Local", "Any", "Any"]
        pr.ancestorDepths = [1, 0, 0]
        pr._applyOptionalCorrections()
        prodsTypeListExpected = ["MCSimulation", "Merge", "Merge"]
        pluginsExpected = ["", "ByRunFileTypeSizeWithFlush", "RootMerging"]
        stepsListDictExpected = [stepMC, mergeStep, stepHistoMergingDict]
        stepsInProdExpected = [[1], [2], [3]]
        outputSEsExpected = ["Tier1-DST", "Tier1-M-DST", "Tier1-M-DST"]
        prioritiesExpected = [1, 4, 5]
        cpusExpected = [10, 100, 100]
        groupSizesExpected = [1, 2, 3]
        bkQueriesExpected = ["", "fromPreviousProd", "fromPreviousProd"]
        previousProdsExpected = [None, 1, 2]
        removeInputsFlagExpected = [False, True, True]
        outputFileMasksExpected = ["", "dst", "root"]
        outputFileStepsExpected = ["", "2", "3"]
        inputsExpected = [[], [], []]
        inputDataPoliciesExpected = ["", "dl", "dl"]
        eventsExpected = [100, -1, -1]
        targetsExpected = ["Target1", "Target2", "T3"]
        multicoreExpected = ["False", "True", "True"]
        processorsExpected = [2, 0, 0]
        outputModeExpected = ["Local", "Any", "Any"]
        ancestorDepthsExpected = [1, 0, 0]
        self.assertEqual(pr.prodsTypeList, prodsTypeListExpected)
        self.assertEqual(pr.plugins, pluginsExpected)
        self.assertEqual(pr.stepsListDict, stepsListDictExpected)
        self.assertEqual(pr.stepsInProds, stepsInProdExpected)
        self.assertEqual(pr.outputSEs, outputSEsExpected)
        self.assertEqual(pr.priorities, prioritiesExpected)
        self.assertEqual(pr.cpus, cpusExpected)
        self.assertEqual(pr.groupSizes, groupSizesExpected)
        self.assertEqual(pr.bkQueries, bkQueriesExpected)
        self.assertEqual(pr.previousProds, previousProdsExpected)
        self.assertEqual(pr.removeInputsFlags, removeInputsFlagExpected)
        self.assertEqual(pr.outputFileMasks, outputFileMasksExpected)
        self.assertEqual(pr.outputFileSteps, outputFileStepsExpected)
        self.assertEqual(pr.inputs, inputsExpected)
        self.assertEqual(pr.inputDataPolicies, inputDataPoliciesExpected)
        self.assertEqual(pr.events, eventsExpected)
        self.assertEqual(pr.targets, targetsExpected)
        self.assertEqual(pr.multicore, multicoreExpected)
        self.assertEqual(pr.processors, processorsExpected)
        self.assertEqual(pr.outputModes, outputModeExpected)
        self.assertEqual(pr.ancestorDepths, ancestorDepthsExpected)

    def test_getProdsDescriptionDict(self):
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.stepsList = [123, 456, 456, 456, 789]
        pr.prodsTypeList = ["DataStripping", "Merge", "Merge", "Merge"]
        pr.removeInputsFlags = [False, True, True, True]
        pr.inputs = [[], [], [], []]
        pr.targets = ["", "", "", ""]
        pr.groupSizes = [1, 1, 2, 3]
        pr.inputDataPolicies = ["download", "download", "download", "download"]
        pr.outputFileMasks = ["", "", "", ""]
        pr.outputFileSteps = ["", "", "", ""]
        pr.stepsInProds = [[1, 2], [3], [4], [5]]
        pr.bkQueries = ["Full", "fromPreviousProd", "fromPreviousProd", "fromPreviousProd"]
        #     pr.outputSEs = ['Tier1-Buffer', 'Tier1-DST', 'Tier1-DST']
        #     pr.specialOutputSEs = [{}, {}, {}]
        pr.outputSEsPerFileType = [{"T1": "SE1"}, {"T1": "SE1"}, {"T1": "SE1"}, {"T1": "SE1"}]
        pr.priorities = [5, 8, 9, 9]
        pr.cpus = [1000000, 300000, 10000, 1000]
        pr.plugins = ["ByRun", "BySize", "BySize", "BySize"]
        pr.previousProds = [None, 1, 1, 1]
        pr.events = [-1, -1, -1, -1]
        pr.multicore = ["False", "False", "True", "True"]
        pr.processors = [(4, 4), (2, 2), (0, 2), (0, 0)]
        pr.outputModes = ["Any", "Local", "Any", "Any"]
        pr.ancestorDepths = [0, 0, 0, 0]

        pr.stepsListDict = [
            {
                "StepId": 123,
                "StepName": "Stripping14-Stripping",
                "ApplicationName": "DaVinci",
                "ApplicationVersion": "v2r2",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "False",
                "fileTypesIn": ["SDST"],
                "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
            },
            {
                "StepId": 456,
                "StepName": "Merge",
                "ApplicationName": "LHCb",
                "ApplicationVersion": "v1r2",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "False",
                "prodStepID": "456['BHADRON.DST']",
                "fileTypesIn": ["BHADRON.DST"],
                "fileTypesOut": ["BHADRON.DST"],
            },
            {
                "StepId": 456,
                "StepName": "Merge",
                "ApplicationName": "LHCb",
                "ApplicationVersion": "v1r2",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "False",
                "prodStepID": "456['CALIBRATION.DST']",
                "fileTypesIn": ["CALIBRATION.DST"],
                "fileTypesOut": ["CALIBRATION.DST"],
            },
            {
                "StepId": 456,
                "StepName": "Merge",
                "ApplicationName": "LHCb",
                "ApplicationVersion": "v1r2",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "False",
                "prodStepID": "456['PID.MDST']",
                "fileTypesIn": ["PID.MDST"],
                "fileTypesOut": ["PID.MDST"],
            },
            {
                "StepId": 789,
                "StepName": "Merge",
                "ApplicationName": "Noether",
                "ApplicationVersion": "v1r2",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "False",
                "prodStepID": "789['DAVINCIHIST', 'BRUNELHIST']",
                "fileTypesIn": ["DAVINCIHIST", "BRUNELHIST"],
                "fileTypesOut": ["ROOT"],
            },
        ]
        res = pr._getProdsDescriptionDict()

        self.maxDiff = None
        self.assertEqual(res, prodsDict)

    def test__addStepsToProd(self):
        stepsInProd = [
            {
                "StepId": 123,
                "StepName": "Stripping14-Stripping",
                "ApplicationName": "DaVinci",
                "ApplicationVersion": "v2r2",
                "ExtraOptions": "",
                "EventTimeout": "",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "SystemConfig": "",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "N",
                "prodStepID": "123['SDST']",
                "mcTCK": "",
                "visibilityFlag": [
                    {"Visibility": "N", "FileType": "BHADRON.DST"},
                    {"Visibility": "N", "FileType": "CALIBRATION.DST"},
                ],
                "fileTypesIn": ["SDST"],
                "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
            },
            {
                "StepId": 456,
                "StepName": "Merge",
                "ApplicationName": "LHCb",
                "ApplicationVersion": "v1r2",
                "ExtraOptions": "",
                "EventTimeout": "",
                "OptionFiles": "optsFiles",
                "Visible": "Yes",
                "ExtraPackages": "eps",
                "ProcessingPass": "procPass",
                "OptionsFormat": "",
                "SystemConfig": "x86_64+avx2-centos7-gcc7-opt",
                "prodStepID": "456['BHADRON.DST', 'CALIBRATION.DST']",
                "DDDB": "",
                "CONDDB": "123456",
                "DQTag": "",
                "isMulticore": "N",
                "mcTCK": "",
                "visibilityFlag": [
                    {"Visibility": "Y", "FileType": "BHADRON.DST"},
                    {"Visibility": "Y", "FileType": "CALIBRATION.DST"},
                ],
                "fileTypesIn": ["BHADRON.DST", "CALIBRATION.DST"],
                "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST"],
            },
        ]

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        prod = Production()
        prod = pr._addStepsToProd(prod, stepsInProd, True)
        self.assertEqual(prod.gaudiSteps, ["DaVinci_1", "LHCb_2"])

    # def test__getStepsInProdDAG( self ):

    #   pr = ProductionRequest( self.bkClientFake, self.diracProdIn )
    #   # stepsListDict = {}
    #   # for prodDict in prodsDict.values():
    #   #   stepsInProdDAG = pr._getStepsInProdDAG(prodDict, stepsListDict)
    #   #   self.assertEqual(stepsInProdDAG.graph, {})

    #   stepsListDict = [step1Dict, mergeStepBHADRON]
    #   stepsInProdDAG = pr._getStepsInProdDAG(prodsDict[1], stepsListDict)

    #   self.assertEqual(
    #       stepsInProdDAG.graph,
    #       {frozenset([('DDDB', ''),
    #                   ('ExtraPackages', 'eps'),
    #                   ('OptionsFormat', ''),
    #                   ('visibilityFlag', frozenset([
    #                       {'Visible':'N', 'FileType': 'BHADRON.DST'},
    #                       {'Visible':'N', 'FileType': 'CALIBRATION.DST'},
    #                   ])),
    #                   ('fileTypesOut', frozenset(['CALIBRATION.DST', 'BHADRON.DST'])),
    #                   ('DQTag', ''),
    #                   ('CONDDB', '123456'),
    #                   ('mcTCK', ''),
    #                   ('ApplicationName', 'DaVinci'),
    #                   ('ApplicationVersion', 'v2r2'),
    #                   ('Visible', 'Yes'),
    #                   ('ProcessingPass', 'procPass'),
    #                   ('fileTypesIn', frozenset(['SDST'])),
    #                   ('isMulticore', 'N'),
    #                   ('SystemConfig', ''),
    #                   ('prodStepID', "123['SDST']"),
    #                   ('StepName', 'Stripping14-Stripping'),
    #                   ('StepId', 123),
    #                   ('OptionFiles', 'optsFiles'),
    #                   ('ExtraOptions', '')]): set([frozenset([
    #                       ('DDDB', 'head-20110302'),
    #                       ('ExtraPackages', 'AppConfig.v3r104'),
    #                       ('fileTypesOut', frozenset(['BHADRON.DST'])),
    #                       ('CONDDB', 'head-20110407'),
    #                       ('mcTCK', ''),
    #                       ('visibilityFlag', frozenset([''])),
    #                       ('ApplicationName', 'DaVinci'),
    #                       ('ApplicationVersion', 'v28r3p1'),
    #                       ('ProcessingPass', 'Merging'),
    #                       ('fileTypesIn', frozenset(['BHADRON.DST'])),
    #                       ('prodStepID', "456['BHADRON.DST']"),
    #                       ('StepName', 'Stripping14-Merging'),
    #                       ('StepId', 456),
    #                       ('SystemConfig', ''),
    #                       ('Usable', 'Yes'),
    #                       ('Visible', 'N'),
    #                       ('OptionFiles', '$APPCONFIGOPTS/Merging/DV-Stripping14-Merging.py')
    #                   ])]),
    #         frozenset([('DDDB', 'head-20110302'),
    #                   ('ExtraPackages', 'AppConfig.v3r104'),
    #                   ('fileTypesOut', frozenset(['BHADRON.DST'])),
    #                   ('CONDDB', 'head-20110407'),
    #                   ('mcTCK', ''),
    #                   ('visibilityFlag', frozenset([''])),
    #                   ('ApplicationName', 'DaVinci'),
    #                   ('ApplicationVersion', 'v28r3p1'),
    #                   ('ProcessingPass', 'Merging'),
    #                   ('fileTypesIn', frozenset(['BHADRON.DST'])),
    #                   ('prodStepID', "456['BHADRON.DST']"),
    #                   ('StepName', 'Stripping14-Merging'),
    #                   ('StepId', 456),
    #                   ('SystemConfig', ''),
    #                   ('Usable', 'Yes'),
    #                   ('Visible', 'N'),
    #                   ('OptionFiles', '$APPCONFIGOPTS/Merging/DV-Stripping14-Merging.py')]): set([]),
    #       }
    #     )

    def test__getBKKQuery(self):
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dataTakingConditions = "dataTC"
        pr.processingPass = "procePass"
        pr.dqFlag = "OK,AA, BB"
        pr.startRun = "123"
        pr.endRun = "456"
        res = pr._getBKKQuery()

        resExpected = {
            "DataTakingConditions": "dataTC",
            "ProcessingPass": "procePass",
            "FileType": "",
            "EventType": "",
            "ConfigName": "test",
            "ConfigVersion": "certification",
            "DataQualityFlag": "OK;;;AA;;;BB",
            "StartRun": 123,
            "EndRun": 456,
        }
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dataTakingConditions = "dataTC"
        pr.processingPass = "procePass"
        pr.dqFlag = "OK,AA, BB"
        pr.bkFileType = ["type1", "type2"]
        pr.startRun = "123"
        pr.endRun = "456"
        res = pr._getBKKQuery()
        resExpected = {
            "DataTakingConditions": "dataTC",
            "ProcessingPass": "procePass",
            "FileType": "type1;;;type2",
            "EventType": "",
            "ConfigName": "test",
            "ConfigVersion": "certification",
            "DataQualityFlag": "OK;;;AA;;;BB",
            "StartRun": 123,
            "EndRun": 456,
        }
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dataTakingConditions = "dataTC"
        pr.processingPass = "procePass"
        pr.dqFlag = "OK,AA, BB"
        pr.bkFileType = ["type1"]
        pr.startRun = "123"
        pr.endRun = "456"
        res = pr._getBKKQuery()
        resExpected = {
            "DataTakingConditions": "dataTC",
            "ProcessingPass": "procePass",
            "FileType": "type1",
            "EventType": "",
            "ConfigName": "test",
            "ConfigVersion": "certification",
            "DataQualityFlag": "OK;;;AA;;;BB",
            "StartRun": 123,
            "EndRun": 456,
        }
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dataTakingConditions = "dataTC"
        pr.processingPass = "procePass"
        pr.dqFlag = "OK,AA, BB"
        pr.bkFileType = "type1"
        pr.startRun = "123"
        pr.endRun = "456"
        res = pr._getBKKQuery()
        resExpected = {
            "DataTakingConditions": "dataTC",
            "ProcessingPass": "procePass",
            "FileType": "type1",
            "EventType": "",
            "ConfigName": "test",
            "ConfigVersion": "certification",
            "DataQualityFlag": "OK;;;AA;;;BB",
            "StartRun": 123,
            "EndRun": 456,
        }
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dataTakingConditions = "dataTC"
        pr.processingPass = "procePass"
        pr.dqFlag = "OK,AA, BB"
        pr.bkFileType = "type1, type2"
        pr.startRun = "123"
        pr.endRun = "456"
        res = pr._getBKKQuery()
        resExpected = {
            "DataTakingConditions": "dataTC",
            "ProcessingPass": "procePass",
            "FileType": "type1;;;type2",
            "EventType": "",
            "ConfigName": "test",
            "ConfigVersion": "certification",
            "DataQualityFlag": "OK;;;AA;;;BB",
            "StartRun": 123,
            "EndRun": 456,
        }
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dqFlag = "OK,AA, BB"
        res = pr._getBKKQuery("fromPreviousProd", ["type"], 123)
        resExpected = {"ProductionID": 123, "FileType": "type", "DataQualityFlag": "OK;;;AA;;;BB"}
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dqFlag = "OK,AA, BB"
        res = pr._getBKKQuery("fromPreviousProd", ["type"], 123)
        resExpected = {"ProductionID": 123, "FileType": "type", "DataQualityFlag": "OK;;;AA;;;BB"}
        self.assertEqual(res, resExpected)

        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.dqFlag = "OK,AA, BB"
        res = pr._getBKKQuery("fromPreviousProd", ["type1", "type2"], 123)
        resExpected = {"ProductionID": 123, "FileType": "type1;;;type2", "DataQualityFlag": "OK;;;AA;;;BB"}
        self.assertEqual(res, resExpected)

    def test__splitIntoProductionSteps(self):
        r_p = _splitIntoProductionSteps(stepStripp)
        r_exp = [
            {
                "ApplicationName": "DaVinci",
                "Usable": "Yes",
                "StepId": 123,
                "ApplicationVersion": "v28r3p1",
                "ExtraPackages": "AppConfig.v3r104",
                "StepName": "Stripping14-Merging",
                "SystemConfig": "",
                "ProcessingPass": "Merging",
                "Visible": "N",
                "DDDB": "head-20110302",
                "mcTCK": "",
                "OptionFiles": "$APPCONFIGOPTS/Merging/DV-Stripping14-Merging.py",
                "CONDDB": "head-20110407",
                "visibilityFlag": [],
                "fileTypesIn": ["SDST"],
                "fileTypesOut": ["BHADRON.DST", "CALIBRATION.DST", "CHARM.MDST", "CHARMCOMPLETEEVENT.DST"],
            }
        ]

        self.assertEqual(r_p, r_exp)

        r_p = _splitIntoProductionSteps(mergeStep)
        r_exp = [
            {
                "ApplicationName": "DaVinci",
                "Usable": "Yes",
                "StepId": 456,
                "ApplicationVersion": "v28r3p1",
                "ExtraPackages": "AppConfig.v3r104",
                "StepName": "Stripping14-Merging",
                "SystemConfig": "",
                "prodStepID": "456['BHADRON.DST']",
                "mcTCK": "",
                "ProcessingPass": "Merging",
                "Visible": "N",
                "DDDB": "head-20110302",
                "OptionFiles": "$APPCONFIGOPTS/Merging/DV-Stripping14-Merging.py",
                "CONDDB": "head-20110407",
                "visibilityFlag": [],
                "fileTypesIn": ["BHADRON.DST"],
                "fileTypesOut": ["BHADRON.DST"],
            },
            {
                "ApplicationName": "DaVinci",
                "Usable": "Yes",
                "StepId": 456,
                "ApplicationVersion": "v28r3p1",
                "ExtraPackages": "AppConfig.v3r104",
                "StepName": "Stripping14-Merging",
                "SystemConfig": "",
                "prodStepID": "456['CALIBRATION.DST']",
                "mcTCK": "",
                "ProcessingPass": "Merging",
                "Visible": "N",
                "DDDB": "head-20110302",
                "OptionFiles": "$APPCONFIGOPTS/Merging/DV-Stripping14-Merging.py",
                "CONDDB": "head-20110407",
                "visibilityFlag": [],
                "fileTypesIn": ["CALIBRATION.DST"],
                "fileTypesOut": ["CALIBRATION.DST"],
            },
            {
                "ApplicationName": "DaVinci",
                "Usable": "Yes",
                "StepId": 456,
                "ApplicationVersion": "v28r3p1",
                "ExtraPackages": "AppConfig.v3r104",
                "StepName": "Stripping14-Merging",
                "SystemConfig": "",
                "prodStepID": "456['PID.MDST']",
                "mcTCK": "",
                "ProcessingPass": "Merging",
                "Visible": "N",
                "DDDB": "head-20110302",
                "OptionFiles": "$APPCONFIGOPTS/Merging/DV-Stripping14-Merging.py",
                "CONDDB": "head-20110407",
                "visibilityFlag": [],
                "fileTypesIn": ["PID.MDST"],
                "fileTypesOut": ["PID.MDST"],
            },
        ]

        self.assertEqual(r_p, r_exp)


class ProductionRequestFailure(ClientTestCase):
    def test_resolveStepsFailure(self):
        pr = ProductionRequest(self.bkClientMock, self.diracProdIn)
        pr.stepsList = ["123"]
        self.bkClientMock.getAvailableSteps.return_value = {"OK": False, "Message": "error"}
        self.assertRaises(ValueError, pr.resolveSteps)

        self.bkClientMock.getStepInputFiles.return_value = {"OK": False, "Message": "error"}
        self.assertRaises(ValueError, pr.resolveSteps)


class ProductionRequestFullChain(ClientTestCase):
    def test_full(self):
        pr = ProductionRequest(self.bkClientFake, self.diracProdIn)
        pr.logger.setLevel("VERBOSE")

        stepsList = ["123"]
        stepsList.append("456")
        stepsList.append("")
        stepsList.append("")
        stepsList.append("")
        pr.stepsList = stepsList
        pr.compressionLvl = ["LOW"] * 4
        pr.outputVisFlag = [{"1": "N"}, {"2": "N"}]
        pr.resolveSteps()

        pr.appendName = "1"
        pr.configName = "MC"
        pr.configVersion = "MC11a"

        pr.events = ["100", "-1"]

        pr.eventsToProduce = 10000

        pr.eventType = "11124001"
        pr.parentRequestID = "34"
        pr.requestID = "35"

        pr.prodGroup = "Sim05/Trig0x40760037Flagged/Reco12a/Stripping17Flagged"
        pr.dataTakingConditions = "Beam3500GeV-2011-MagDown-Nu2-EmNoCuts"

        pr.prodsTypeList = ["Stripping", "Merge"]
        pr.outputSEs = ["Tier1_MC-DST", "Tier1_MC-DST"]
        pr.specialOutputSEs = [{}, {}]
        pr.stepsInProds = [range(1, len(pr.stepsList)), [len(pr.stepsList)]]
        pr.removeInputsFlags = [False, True]
        pr.priorities = [1, 6]
        pr.cpus = [1000, 100]
        pr.outputModes = ["Local", "Any"]
        pr.outputFileMasks = ["FOO", ""]
        pr.outputFileSteps = ["2", ""]
        pr.targets = ["Tier2", ""]
        pr.groupSizes = [1, 5]
        pr.plugins = ["", "BySize"]
        pr.inputDataPolicies = ["", "protocol"]
        pr.inputs = [[], []]

        res = pr.buildAndLaunchRequest()

        self.assertEqual(res, {"OK": True, "Value": [321, 321, 321]})


# ###########################################################################
# Test Suite run
# ###########################################################################


if __name__ == "__main__":
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(ClientTestCase)
    suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(ProductionRequestSuccess))
    suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(ProductionRequestFailure))
    suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(ProductionRequestFullChain))
    testResult = unittest.TextTestRunner(verbosity=2).run(suite)

# EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#
