3 import os, sys, re, time
6 from threading
import Thread
20 def doCmd(self, cmd, dryRun=False):
22 msg =
"\n# in: " +os.getcwd()
23 if dryRun: msg +=
" dryRun for '"
24 else: msg +=
" going to execute "
25 msg += cmd.replace(
';',
'\n')
28 cmdLog = open(self.wf.numId+
'_'+self.wf.nameId+
'/cmdLog',
'a')
29 cmdLog.write(msg+
'\n')
36 print "ERROR executing ",cmd,
'ret=', ret
42 startDir = os.getcwd()
44 wfDir = self.wf.numId+
'_'+self.wf.nameId
45 if not os.path.exists(wfDir):
49 if os.path.exists( os.path.join(os.environ[
"CMS_PATH"],
'cmsset_default.sh') ) :
50 preamble =
'source $CMS_PATH/cmsset_default.sh; '
52 preamble =
'source $CMS_PATH/sw/cmsset_default.sh; '
53 preamble +=
'eval `scram run -sh`; '
54 preamble +=
'cd '+wfDir+
'; '
55 preamble +=
'ulimit -v 4069000;'
57 startime=
'date %s' %time.asctime()
64 if not self.wf.cmdStep2: stat2 =
'NOSTEP'
65 if not self.wf.cmdStep3: stat3 =
'NOSTEP'
66 if not self.wf.cmdStep4: stat4 =
'NOSTEP'
71 inFile =
'file:raw.root'
72 if 'REALDATA' in self.wf.cmdStep1:
73 realDataRe = re.compile(
'REALDATA:\s*(/[A-Za-z].*?),(\s*RUN:\s*(?P<run>\d+),)?(\s*FILES:\s*(?P<files>\d+),)?(\s*EVENTS:\s*(?P<events>\d+))?,\s*LABEL:\s*(?P<label>.*),\s*LOCATION:\s*(?P<location>.*)\s*')
74 realDataMatch = realDataRe.match(self.wf.cmdStep1)
77 if realDataMatch.group(
"run") : run = realDataMatch.group(
"run")
78 label = realDataMatch.group(
"label")
79 location = realDataMatch.group(
"location").lower().
strip()
81 print "ignoring workflow ",self.wf.numId, self.wf.nameId,
' as this is on CAF ...'
82 self.
npass = [0,0,0,0]
83 self.
nfail = [0,0,0,0]
85 logStat =
'Step1-NOTRUN Step2-NOTRUN Step3-NOTRUN Step4-NOTRUN '
86 self.
report+=
'%s_%s %s - time %s; exit: %s %s %s %s \n' % (self.wf.numId, self.wf.nameId, logStat, 0, 0,0,0,0)
91 if realDataMatch.group(
"files"):
92 files = realDataMatch.group(
"files")
93 if realDataMatch.group(
"events"):
94 events = realDataMatch.group(
"events")
95 if self.wf.cmdStep2
and ' -n ' not in self.wf.cmdStep2: self.wf.cmdStep2 +=
' -n ' + events
96 if self.wf.cmdStep3
and ' -n ' not in self.wf.cmdStep3: self.wf.cmdStep3 +=
' -n ' + events
97 if self.wf.cmdStep4
and ' -n ' not in self.wf.cmdStep4: self.wf.cmdStep4 +=
' -n ' + events
99 print "run, files, events, label", run, files, events, label
100 cmd +=
'dbs search --noheader --url=http://cmsdbsprod.cern.ch/cms_dbs_prod_global/servlet/DBSServlet '
101 cmd +=
"--query='find file where dataset like "+realDataMatch.group(1)
102 if run: cmd +=
" and run=" + run
104 cmd +=
' > %s 2>&1; ' % (
'step1_'+self.wf.nameId+
'-dbsquery.log',)
105 retStep1 = self.
doCmd(cmd)
107 lf = open(wfDir+
'/step1_'+self.wf.nameId+
'-dbsquery.log',
'r')
108 lines = lf.readlines()
110 if not lines
or len(lines)==0 :
111 inFile =
"NoFileFoundInDBS"
115 inFile = lines[0].
strip()
117 print "ERROR determining file from DBS query: ", str(e)
118 inFile =
"NoFileFoundInDBS"
121 print "ERROR: found REALDATA in '"+self.wf.cmdStep1+
"' but not RE match !!??!"
124 cmd += self.wf.cmdStep1 +
' --fileout file:raw.root '
125 cmd +=
' > %s 2>&1; ' % (
'step1_'+self.wf.nameId+
'.log ',)
126 retStep1 = self.
doCmd(cmd)
128 print " ... ret: " , retStep1
135 if self.wf.cmdStep2
and retStep1 == 0:
137 fullcmd += self.wf.cmdStep2
138 if ' -n ' not in fullcmd : fullcmd +=
' -n -1 '
139 fullcmd +=
' --fileout file:reco.root '
140 print '=====>>> ', self.wf.nameId, self.wf.numId
145 if (
'40.0' in str(self.wf.numId) ) :
146 fullcmd +=
' --himix '
147 inFile =
'/store/relval/CMSSW_3_9_7/RelValPyquen_ZeemumuJets_pt10_2760GeV/GEN-SIM-DIGI-RAW-HLTDEBUG/START39_V7HI-v1/0054/102FF831-9B0F-E011-A3E9-003048678BC6.root'
148 if (
'41.0' in str(self.wf.numId) ) :
149 fullcmd +=
' --himix '
150 inFile =
'/store/relval/CMSSW_3_9_7/RelValPyquen_GammaJet_pt20_2760GeV/GEN-SIM-DIGI-RAW-HLTDEBUG/START39_V7HI-v1/0054/06B4F699-A50F-E011-AD62-0018F3D0962E.root'
152 fullcmd +=
' --filein '+inFile+
' '
153 fullcmd +=
' > %s 2>&1; ' % (
'step2_'+self.wf.nameId+
'.log ',)
155 retStep2 = self.
doCmd(fullcmd)
158 if self.wf.cmdStep3
and retStep2 == 0:
160 fullcmd += self.wf.cmdStep3
161 if ' -n ' not in fullcmd : fullcmd +=
' -n -1 '
163 if not '134' in str(self.wf.numId):
164 if 'HARVESTING' in fullcmd
and not 'filein' in fullcmd:
165 fullcmd +=
' --filein file:reco_inDQM.root --fileout file:step3.root '
167 fullcmd +=
' --filein file:reco.root --fileout file:step3.root '
168 fullcmd +=
' > %s 2>&1; ' % (
'step3_'+self.wf.nameId+
'.log ',)
170 retStep3 = self.
doCmd(fullcmd)
172 if self.wf.cmdStep4
and retStep3 == 0:
174 fullcmd += self.wf.cmdStep4
175 if ' -n ' not in fullcmd : fullcmd +=
' -n -1 '
177 if not '134' in str(self.wf.numId):
178 fullcmd +=
' --filein file:step3.root '
179 fullcmd +=
' > %s 2>&1; ' % (
'step4_'+self.wf.nameId+
'.log ',)
181 retStep4 = self.
doCmd(fullcmd)
186 endtime=
'date %s' %time.asctime()
187 tottime=
'%s-%s'%(endtime,startime)
189 self.
nfail = [0,0,0,0]
190 self.
npass = [1,1,1,1]
191 if 'NOSTEP' in stat2:
192 self.
npass = [1,0,0,0]
194 if 'NOSTEP' in stat3 :
195 self.
npass = [1,1,0,0]
196 if 'NOSTEP' in stat4 :
197 self.
npass = [1,1,1,0]
203 self.
npass = [0,0,0,0]
204 self.
nfail = [1,0,0,0]
210 self.
npass = [1,0,0,0]
211 self.
nfail = [0,1,0,0]
216 self.
npass = [1,1,0,0]
217 self.
nfail = [0,0,1,0]
221 self.
npass = [1,1,1,0]
222 self.
nfail = [0,0,0,1]
224 logStat =
'Step1-'+stat1+
' Step2-'+stat2+
' Step3-'+stat3+
' '+
' Step4-'+stat4+
' '
225 self.
report+=
'%s_%s %s - time %s; exit: %s %s %s %s \n' % (self.wf.numId, self.wf.nameId, logStat, tottime, retStep1,retStep2,retStep3, retStep4)
234 def __init__(self, num, nameID, cmd1, cmd2=None, cmd3=None, cmd4=None, real=None):
272 'cmsDriver_highstats_hlt.txt':
'hi-' ,
273 'cmsDriver_generator.txt' :
'gen-' ,
278 self.
files = [
'cmsDriver_standard_hlt.txt' ,
279 'cmsDriver_highstats_hlt.txt',
280 'cmsDriver_generator.txt' ,
291 print "processing ", fileNameIn,
295 inFile = open(fileNameIn,
'r')
296 print ' from local developer area',
298 baseRelPath = os.environ[
'CMSSW_BASE']
301 inFile = open( os.path.join(baseRelPath,
'src/Configuration/PyReleaseValidation/data' ,fileNameIn),
'r')
302 print ' from ', baseRelPath,
304 baseRelPath = os.environ[
'CMSSW_RELEASE_BASE']
306 inFile = open( os.path.join(baseRelPath,
'src/Configuration/PyReleaseValidation/data' ,fileNameIn),
'r')
307 print ' from ', baseRelPath,
308 lines = inFile.readlines()
311 print "ERROR reading in file ", fileNameIn, str(e)
314 print " found ", len(lines),
'entries.'
316 realRe = re.compile(
'\s*([1-9][0-9]*\.*[0-9]*)\s*\+\+\s*(.*?)\s*\+\+\s*(.*?)\s*\+\+\s*(.*?)\s*@@@\s*(.*)\s*')
317 step1Re = re.compile(
'\s*([1-9][0-9]*\.*[0-9]*)\s*\+\+\s*(.*?)\s*\+\+\s*(.*?)\s*@@@\s*(.*)\s*')
318 step2Re = re.compile(
'\s*STEP2\s*\+\+\s*(\S*)\s*@@@\s*(.*)\s*')
319 step3Re = re.compile(
'\s*STEP3\s*\+\+\s*(\S*)\s*@@@\s*(.*)\s*')
320 step4Re = re.compile(
'\s*STEP4\s*\+\+\s*(\S*)\s*@@@\s*(.*)\s*')
322 line = lineIn.strip()
324 realMatch = realRe.match(line)
326 num = realMatch.group(1).
strip()
329 cmd = realMatch.group(4).
strip()
337 step2 = steps[0].
strip()
339 step3 = steps[1].
strip()
341 step4 = steps[2].
strip()
343 self.
step1WorkFlows[(float(num),prefix)] = (str(float(num)), name, step2, step3, step4, cmd,
None)
347 step1Match = step1Re.match(line)
349 num = step1Match.group(1).
strip()
352 cmd = step1Match.group(4).
strip()
359 step2 = steps[0].
strip()
361 step3 = steps[1].
strip()
363 step4 = steps[2].
strip()
365 self.
step1WorkFlows[(float(num),prefix)] = (str(float(num)), name, step2, step3, step4, cmd,
None)
368 step2Match = step2Re.match(line)
370 name = step2Match.group(1).
strip()
371 cmd = step2Match.group(2).
strip()
375 step3Match = step3Re.match(line)
377 name = step3Match.group(1).
strip()
378 cmd = step3Match.group(2).
strip()
382 step4Match = step4Re.match(line)
384 name = step4Match.group(1).
strip()
385 cmd = step4Match.group(2).
strip()
393 print "found ", len(self.step1WorkFlows.keys()),
' workflows for step1:'
394 ids = self.step1WorkFlows.keys()
398 print key[0],
':', val
400 print "found ", len(self.step2WorkFlows.keys()),
' workflows for step2:'
401 for key, val
in self.step2WorkFlows.items():
404 print "found ", len(self.step3WorkFlows.keys()),
' workflows for step3:'
405 for key, val
in self.step3WorkFlows.items():
408 print "found ", len(self.step4WorkFlows.keys()),
' workflows for step4:'
409 for key, val
in self.step4WorkFlows.items():
417 fmt1 =
"%-6s %-35s [1]: %s ..."
418 fmt2 =
" %35s [%d]: %s ..."
419 print "\nfound a total of ", len(self.
workFlows),
' workflows:'
421 print " of which the following", len(selected),
'were selected:'
423 fmt1 =
"%-6s %-35s [1]: %s "
424 fmt2 =
" %35s [%d]: %s"
430 if selected
and float(wf.numId)
not in selected:
continue
432 print fmt1 % (wf.numId, wf.nameId, (wf.cmdStep1+
' ')[:maxLen])
435 print fmt2 % (
' ', 2, (wf.cmdStep2+
' ')[:maxLen])
438 print fmt2 % (
' ', 3, (wf.cmdStep3+
' ')[:maxLen])
441 print fmt2 % (
' ', 4, (wf.cmdStep4+
' ')[:maxLen])
443 print n1,
'workflows for step1,'
444 print n2,
'workflows for step1 + step2,'
445 print n3,
'workflows for step1 + step2 + step3'
446 print n4,
'workflows for step1 + step2 + step3 + step4'
455 keyList = self.step1WorkFlows.keys()
459 if pref != prefixIn :
continue
460 ids.append( float(id) )
469 num, name, step2, step3, step4, cmd, real = val
470 nameId = num+
'_'+name
471 if step2.lower() !=
'none':
473 if step3.lower() !=
'none':
475 if step4.lower() !=
'none':
477 if nameId
in self.nameList.keys():
478 print "==> duplicate name found for ", nameId
479 print ' keeping : ', self.
nameList[nameId]
480 print ' ignoring : ', val
490 if step2.lower() !=
'none':
493 if step3.lower() !=
'none':
496 if step4.lower() !=
'none':
500 self.workFlows.append(
WorkFlow(num, name, cmd, cmd2, cmd3, cmd4) )
506 for matrixFile
in self.
files:
510 print "ERROR reading file:", matrixFile, str(e)
515 print "ERROR creating workflows :", str(e)
520 print '\n',
'-'*80,
'\n'
526 pickle.dump(self.
workFlows, open(
'theMatrix.pkl',
'w') )
546 if t.isAlive() : nActive += 1
553 startDir = os.getcwd()
556 if not os.environ.has_key(
'CMS_PATH'):
557 cmsPath =
'/afs/cern.ch/cms'
558 print "setting default for CMS_PATH to", cmsPath
559 os.environ[
'CMS_PATH'] = cmsPath
562 print 'Running in %s thread(s)' % self.
maxThreads
566 if testList
and float(wf.numId)
not in [float(x)
for x
in testList]:
continue
569 if wf.real :
continue
572 if os.path.islink(item) :
continue
579 print '\nPreparing to run %s %s' % (wf.numId, item)
585 self.threadList.append(current)
587 time.sleep(random.randint(1,5))
590 while self.activeThreads() > 0:
603 for pingle
in self.threadList:
606 nfail1 += pingle.nfail[0]
607 nfail2 += pingle.nfail[1]
608 nfail3 += pingle.nfail[2]
609 nfail4 += pingle.nfail[3]
610 npass1 += pingle.npass[0]
611 npass2 += pingle.npass[1]
612 npass3 += pingle.npass[2]
613 npass4 += pingle.npass[3]
614 npass += npass1+npass2+npass3+npass4
615 report += pingle.report
618 msg =
"ERROR retrieving info from thread: " + str(e)
626 report+=
'\n %s %s %s %s tests passed, %s %s %s %s failed\n' %(npass1, npass2, npass3, npass4, nfail1, nfail2, nfail3, nfail4)
629 runall_report_name=
'runall-report-step123-.log'
630 runall_report=open(runall_report_name,
'w')
631 runall_report.write(report)
632 runall_report.close()
657 testList = stdList+hiStatList
661 mrd.show([float(x)
for x
in testList])
662 print 'selected items:', testList
665 ret = mRunnerHi.runTests(testList)
671 def runData(testList, nThreads=4, show=False) :
679 if not testList
or testList == [
'all']:
682 mrd.show([float(x)
for x
in testList])
683 print 'selected items:', testList
686 if not testList
or testList == [
'all']:
687 ret = mRunnerHi.runTests()
689 ret = mRunnerHi.runTests(testList)
695 def runAll(testList=None, nThreads=4, show=False) :
704 print "nThreads = ",nThreads
707 ret = mRunnerHi.runTests()
719 print "found request to run relvals only for ",what
725 print "Usage:", sys.argv[0],
' [options] '
727 Where options is one of the following:
728 -d, --data <list> comma-separated list of workflows to use from the realdata file.
729 <list> can be "all" to select all data workflows
730 -l, --list <list> comma-separated list of workflows to use from the cmsDriver*.txt files
731 -j, --nproc <n> run <n> processes in parallel (default: 4 procs)
732 -s, --selected run a subset of 8 workflows (usually in the CustomIB)
733 -n, -q, --show show the (selected) workflows
735 <list>s should be put in single- or double-quotes to avoid confusion with/by the shell
740 if __name__ ==
'__main__':
745 opts, args = getopt.getopt(sys.argv[1:],
"hj:sl:nqo:d:", [
'help',
"nproc=",
'selected',
'list=',
'showMatrix',
'only=',
'data='])
746 except getopt.GetoptError, e:
747 print "unknown option", str(e)
757 for opt, arg
in opts :
758 if opt
in (
'-h',
'--help'):
761 if opt
in (
'-j',
"--nproc" ):
763 if opt
in (
'-n',
'-q',
'--showMatrix', ):
765 if opt
in (
'-s',
'--selected',) :
767 if opt
in (
'-o',
'--only',) :
769 if opt
in (
'-l',
'--list',) :
771 if opt
in (
'-d',
'--data',) :
772 data = arg.split(
',')
777 ret =
runSelected(testList=sel, nThreads=np, show=show)
779 ret =
runOnly(only=only, show=show, nThreads=np)
781 ret =
runData(testList=data, show=show, nThreads=np)
783 ret =
runAll(show=show, nThreads=np)