Skip to content

Commit a969e1e

Browse files
committed
Add new tests for reduced ProcessHistory using mocked CMSSW release version
The existing test relies on old (4_2_X-time) files.
1 parent 07dfe02 commit a969e1e

File tree

7 files changed

+258
-10
lines changed

7 files changed

+258
-10
lines changed

FWCore/Framework/src/ScheduleItems.cc

+9-2
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,15 @@ namespace edm {
134134

135135
act_table_ = std::make_unique<ExceptionToActionTable>(parameterSet);
136136
std::string processName = parameterSet.getParameter<std::string>("@process_name");
137-
processConfiguration_ = std::make_shared<ProcessConfiguration>(
138-
processName, getReleaseVersion(), getPassID()); // propagate_const<T> has no reset() function
137+
std::string releaseVersion;
138+
if (parameterSet.existsAs<std::string>("@special_override_release_version_only_for_testing", false)) {
139+
releaseVersion =
140+
parameterSet.getUntrackedParameter<std::string>("@special_override_release_version_only_for_testing");
141+
} else {
142+
releaseVersion = getReleaseVersion();
143+
}
144+
// propagate_const<T> has no reset() function
145+
processConfiguration_ = std::make_shared<ProcessConfiguration>(processName, releaseVersion, getPassID());
139146
auto common = std::make_shared<CommonParams>(
140147
parameterSet.getUntrackedParameterSet("maxEvents").getUntrackedParameter<int>("input"),
141148
parameterSet.getUntrackedParameterSet("maxLuminosityBlocks").getUntrackedParameter<int>("input"),

FWCore/ParameterSet/python/Config.py

+19
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ def __init__(self,name: str, *Mods):
149149
self.__isStrict = False
150150
self.__dict__['_Process__modifiers'] = Mods
151151
self.__dict__['_Process__accelerators'] = {}
152+
self.__dict__['_Process__specialOverrideReleaseVersionOnlyForTesting'] = None
152153
self.__injectValidValue('options', Process.defaultOptions_())
153154
self.__injectValidValue('maxEvents', Process.defaultMaxEvents_())
154155
self.maxLuminosityBlocks = Process.defaultMaxLuminosityBlocks_()
@@ -813,6 +814,10 @@ def extend(self,other,items=()):
813814

814815
self.__dict__['_Process__InExtendCall'] = False
815816

817+
def _specialOverrideReleaseVersionOnlyForTesting(self, version):
818+
"This function is intended only for specific framework tests. Do not use for anything else."
819+
self.__specialOverrideReleaseVersionOnlyForTesting = version
820+
816821
def _dumpConfigNamedList(self,items,typeName:str,options:PrintOptions) -> str:
817822
returnValue = ''
818823
for name,item in items:
@@ -1458,6 +1463,8 @@ def __extractPSet(self,pset):
14581463

14591464
self.validate()
14601465
processPSet.addString(True, "@process_name", self.name_())
1466+
if self.__specialOverrideReleaseVersionOnlyForTesting is not None:
1467+
processPSet.addString(False, "@special_override_release_version_only_for_testing", self.__specialOverrideReleaseVersionOnlyForTesting)
14611468
self.handleProcessAccelerators(processPSet)
14621469
all_modules = self.producers_().copy()
14631470
all_modules.update(self.filters_())
@@ -4944,4 +4951,16 @@ def testProcessAccelerator(self):
49444951
self.assertEqual((False, "sp@test1"), p.values["sp"][1].values["@chosen_case"])
49454952
self.assertEqual(["cpu", "test1"], p.values["@available_accelerators"][1])
49464953

4954+
def testProcessSpecialOverrideReleaseVersion(self):
4955+
proc = Process("TEST")
4956+
p = TestMakePSet()
4957+
proc.fillProcessDesc(p)
4958+
self.assertFalse("@special_override_release_version_only_for_testing" in p.values)
4959+
4960+
proc = Process("TEST")
4961+
proc._specialOverrideReleaseVersionOnlyForTesting("CMSSW_15_0_0")
4962+
p = TestMakePSet()
4963+
proc.fillProcessDesc(p)
4964+
self.assertEqual((False, "CMSSW_15_0_0"), p.values["@special_override_release_version_only_for_testing"])
4965+
49474966
unittest.main()

IOPool/Input/test/BuildFile.xml

+1
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@
3838
<lib name="SchemaEvolutionTest"/>
3939
</test>
4040
<test name="TestIOPoolInputRefProductIDMetadataConsistency" command="testRefProductIDMetadataConsistencyRoot.sh"/>
41+
<test name="TestIOPoolInputReducedProcessHistory" command="testReducedProcessHistory.sh"/>
4142

4243
</environment>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
3+
function die { echo $1: status $2 ; exit $2; }
4+
function runSuccess {
5+
echo "cmsRun $@"
6+
cmsRun $@ || die "cmsRun $*" $?
7+
echo
8+
}
9+
function runFailure {
10+
echo "cmsRun $@ (expected to fail)"
11+
cmsRun $@ && die "cmsRun $*" 1
12+
echo
13+
}
14+
15+
VERSION_ARR=(${CMSSW_VERSION//_/ })
16+
VERSION1="${VERSION_ARR[0]}_${VERSION_ARR[1]}_${VERSION_ARR[2]}_0"
17+
VERSION2="${VERSION_ARR[0]}_${VERSION_ARR[1]}_${VERSION_ARR[2]}_1"
18+
VERSION3="${VERSION_ARR[0]}_${VERSION_ARR[1]}_$((${VERSION_ARR[2]}+1))_0"
19+
20+
# Check that changing the patch version does not lead to new lumi or run
21+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistoryCreate_cfg.py --version ${VERSION1} --firstEvent 1 --output version1.root
22+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistoryCreate_cfg.py --version ${VERSION2} --firstEvent 101 --output version2.root
23+
24+
edmProvDump version1.root | grep -q "PROD.*'${VERSION1}'" || die "Did not find ${VERSION1} from version.root provenance" $?
25+
edmProvDump version2.root | grep -q "PROD.*'${VERSION2}'" || die "Did not find ${VERSION2} from version.root provenance" $?
26+
27+
runSuccess ${SCRAM_TEST_PATH}/test_merge_two_files.py version1.root version2.root
28+
29+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistory_cfg.py --input merged_files.root
30+
31+
32+
# Check that changing the minor version leads to new lumi
33+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistoryCreate_cfg.py --version ${VERSION3} --firstEvent 201 --output version3_lumi.root
34+
35+
edmProvDump version3_lumi.root | grep -q "PROD.*'${VERSION3}'" || die "Did not find ${VERSION3} from version3_lumi.root provenance" $?
36+
37+
runSuccess ${SCRAM_TEST_PATH}/test_merge_two_files.py version1.root version3_lumi.root --output merged_files3_lumi.root --bypassVersionCheck
38+
39+
runFailure ${SCRAM_TEST_PATH}/testReducedProcessHistory_cfg.py --input merged_files3_lumi.root --bypassVersionCheck
40+
41+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistory_cfg.py --input merged_files3_lumi.root --bypassVersionCheck --expectNewLumi
42+
43+
44+
# Check that changing the minor version leads to new run
45+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistoryCreate_cfg.py --version ${VERSION3} --firstEvent 201 --lumi 2 --output version3_run.root
46+
47+
edmProvDump version3_run.root | grep -q "PROD.*'${VERSION3}'" || die "Did not find ${VERSION3} from version3_lumi.root provenance" $?
48+
49+
runSuccess ${SCRAM_TEST_PATH}/test_merge_two_files.py version1.root version3_run.root --output merged_files3_run.root --bypassVersionCheck
50+
51+
runFailure ${SCRAM_TEST_PATH}/testReducedProcessHistory_cfg.py --input merged_files3_run.root --bypassVersionCheck
52+
53+
runSuccess ${SCRAM_TEST_PATH}/testReducedProcessHistory_cfg.py --input merged_files3_run.root --bypassVersionCheck --expectNewRun
54+
55+
exit 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import FWCore.ParameterSet.Config as cms
2+
import argparse
3+
4+
parser = argparse.ArgumentParser(description='Create files for reduced ProcessHistory test')
5+
parser.add_argument("--version", type=str, help="CMSSW version to be used in the ProcessHistory")
6+
parser.add_argument("--firstEvent", default=1, type=int, help="Number of first event")
7+
parser.add_argument("--lumi", default=1, type=int, help="LuminosityBlock number")
8+
parser.add_argument("--output", type=str, help="Output file name")
9+
10+
args = parser.parse_args()
11+
12+
process = cms.Process("PROD")
13+
process._specialOverrideReleaseVersionOnlyForTesting(args.version)
14+
15+
process.maxEvents.input = 10
16+
17+
from FWCore.Modules.modules import EmptySource
18+
process.source = EmptySource(
19+
firstEvent = args.firstEvent,
20+
firstLuminosityBlock = args.lumi,
21+
)
22+
23+
from IOPool.Output.modules import PoolOutputModule
24+
process.out = PoolOutputModule(
25+
fileName = args.output
26+
)
27+
28+
from FWCore.Framework.modules import IntProducer
29+
process.intProducer = IntProducer(ivalue = 42)
30+
31+
from FWCore.Integration.modules import ThingWithMergeProducer
32+
process.thingWithMergeProducer = ThingWithMergeProducer()
33+
34+
process.t = cms.Task(
35+
process.intProducer,
36+
process.thingWithMergeProducer,
37+
)
38+
process.p = cms.Path(process.t)
39+
process.ep = cms.EndPath(process.out)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import FWCore.ParameterSet.Config as cms
2+
import argparse
3+
4+
parser = argparse.ArgumentParser(description='Test reduced ProcessHistory')
5+
parser.add_argument("--input", type=str, help="Input file")
6+
parser.add_argument("--bypassVersionCheck", action="store_true", help="Bypass version check")
7+
parser.add_argument("--expectNewLumi", action="store_true", help="Set this if a new lumi is expected between the original files")
8+
parser.add_argument("--expectNewRun", action="store_true", help="Set this if a new run is expected between the original files")
9+
10+
args = parser.parse_args()
11+
12+
process = cms.Process("READ")
13+
14+
from IOPool.Input.modules import PoolSource
15+
process.source = PoolSource(
16+
fileNames = [f"file:{args.input}"],
17+
bypassVersionCheck = args.bypassVersionCheck,
18+
)
19+
20+
from FWCore.Framework.modules import TestMergeResults, RunLumiEventAnalyzer
21+
process.testmerge = TestMergeResults(
22+
expectedBeginRunProd = [10001, 20004, 10003],
23+
expectedEndRunProd = [100001, 200004, 100003],
24+
expectedBeginLumiProd = [101, 204, 103],
25+
expectedEndLumiProd = [1001, 2004, 1003],
26+
27+
expectedBeginRunNew = [10001, 10002, 10003],
28+
expectedEndRunNew = [100001, 100002, 100003],
29+
expectedBeginLumiNew = [101, 102, 103],
30+
expectedEndLumiNew = [1001, 1002, 1003],
31+
expectedProcessHistoryInRuns = [
32+
'PROD',
33+
'MERGETWOFILES',
34+
'READ'
35+
]
36+
)
37+
def setWithMergeAndCopyEntry(p, value):
38+
p[1] = value
39+
p[3:5] = p[0:2]
40+
if args.expectNewLumi or args.expectNewRun:
41+
setWithMergeAndCopyEntry(process.testmerge.expectedBeginRunProd, 10002)
42+
setWithMergeAndCopyEntry(process.testmerge.expectedEndRunProd, 100002)
43+
setWithMergeAndCopyEntry(process.testmerge.expectedBeginLumiProd, 102)
44+
setWithMergeAndCopyEntry(process.testmerge.expectedEndLumiProd, 1002)
45+
46+
process.test = RunLumiEventAnalyzer(
47+
expectedRunLumiEvents = [
48+
1, 0, 0, # beginRun
49+
1, 1, 0, # beginLumi
50+
1, 1, 1,
51+
1, 1, 2,
52+
1, 1, 3,
53+
1, 1, 4,
54+
1, 1, 5,
55+
1, 1, 6,
56+
1, 1, 7,
57+
1, 1, 8,
58+
1, 1, 9,
59+
1, 1, 10,
60+
1, 1, 101,
61+
1, 1, 102,
62+
1, 1, 103,
63+
1, 1, 104,
64+
1, 1, 105,
65+
1, 1, 106,
66+
1, 1, 107,
67+
1, 1, 108,
68+
1, 1, 109,
69+
1, 1, 110,
70+
1, 1, 0, # endLumi
71+
1, 0, 0, # endRun
72+
]
73+
)
74+
endFirstFileIndex = 3*(10+2)
75+
if args.expectNewLumi:
76+
process.test.expectedRunLumiEvents = process.test.expectedRunLumiEvents[:endFirstFileIndex] + [
77+
1, 1, 0, # endLumi
78+
1, 0, 0, # endRun
79+
1, 0, 0, # beginRun
80+
1, 1, 0, # beginLumi
81+
1, 1, 201,
82+
1, 1, 202,
83+
1, 1, 203,
84+
1, 1, 204,
85+
1, 1, 205,
86+
1, 1, 206,
87+
1, 1, 207,
88+
1, 1, 208,
89+
1, 1, 209,
90+
1, 1, 210,
91+
1, 1, 0, # endLumi
92+
1, 0, 0, # endRun
93+
]
94+
elif args.expectNewRun:
95+
process.test.expectedRunLumiEvents = process.test.expectedRunLumiEvents[:endFirstFileIndex] + [
96+
1, 1, 0, # endLumi
97+
1, 0, 0, # endRun
98+
1, 0, 0, # beginRun
99+
1, 2, 0, # beginLumi
100+
1, 2, 201,
101+
1, 2, 202,
102+
1, 2, 203,
103+
1, 2, 204,
104+
1, 2, 205,
105+
1, 2, 206,
106+
1, 2, 207,
107+
1, 2, 208,
108+
1, 2, 209,
109+
1, 2, 210,
110+
1, 2, 0, # endLumi
111+
1, 0, 0, # endRun
112+
]
113+
114+
process.p = cms.Path(
115+
process.testmerge +
116+
process.test
117+
)

IOPool/Input/test/test_merge_two_files.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
import FWCore.ParameterSet.Config as cms
2-
import sys
2+
import argparse
3+
4+
parser = argparse.ArgumentParser(description='Create files for reduced ProcessHistory test')
5+
parser.add_argument("file1", type=str, help="First file to merge")
6+
parser.add_argument("file2", type=str, help="Second file to merge")
7+
parser.add_argument("--output", default="merged_files.root", help="Output file name")
8+
parser.add_argument("--bypassVersionCheck", action="store_true", help="Bypass version check")
9+
10+
args = parser.parse_args()
311

412
process = cms.Process("MERGETWOFILES")
513

6-
process.source = cms.Source("PoolSource",
7-
fileNames = cms.untracked.vstring("file:"+sys.argv[1],
8-
"file:"+sys.argv[2]),
9-
duplicateCheckMode = cms.untracked.string("noDuplicateCheck")
14+
from IOPool.Input.modules import PoolSource
15+
process.source = PoolSource(
16+
fileNames = ["file:"+args.file1,"file:"+args.file2],
17+
duplicateCheckMode = "noDuplicateCheck",
18+
bypassVersionCheck = args.bypassVersionCheck,
1019
)
1120

12-
process.thingWithMergeProducer = cms.EDProducer("ThingWithMergeProducer")
21+
from FWCore.Integration.modules import ThingWithMergeProducer
22+
process.thingWithMergeProducer = ThingWithMergeProducer()
1323

14-
process.out = cms.OutputModule("PoolOutputModule",
15-
fileName = cms.untracked.string("merged_files.root"))
24+
from IOPool.Output.modules import PoolOutputModule
25+
process.out = PoolOutputModule(fileName = args.output)
1626

1727
process.p = cms.Path(process.thingWithMergeProducer)
1828

0 commit comments

Comments
 (0)