CMS 3D CMS Logo

addOnTests.py
Go to the documentation of this file.
1 #! /usr/bin/env python3
2 
3 from __future__ import print_function
4 from builtins import range
5 import os
6 import time
7 import sys
8 import re
9 import random
10 from threading import Thread
11 
12 scriptPath = os.path.dirname( os.path.abspath(sys.argv[0]) )
13 if scriptPath not in sys.path:
14  sys.path.append(scriptPath)
15 
16 class testit(Thread):
17  def __init__(self,dirName, commandList):
18  Thread.__init__(self)
19  self.dirName = dirName
20  self.commandList = commandList
21  self.status=-1
22  self.report=''
23  self.nfail=[]
24  self.npass=[]
25 
26  def run(self):
27  try:
28  os.makedirs(self.dirName)
29  except:
30  pass
31 
32  with open(self.dirName+'/cmdLog', 'w') as clf:
33  clf.write(f'# {self.dirName}\n')
34 
35  for cmdIdx, command in enumerate(self.commandList):
36  clf.write(f'\n{command}\n')
37 
38  time_start = time.time()
39  exitcode = os.system(f'cd {self.dirName} && {command} > step{cmdIdx+1}.log 2>&1')
40  time_elapsed_sec = round(time.time() - time_start)
41 
42  timelog = f'elapsed time: {time_elapsed_sec} sec (ended on {time.asctime()})'
43  logline = f'[{self.dirName}:{cmdIdx+1}] {command} : '
44  if exitcode != 0:
45  logline += 'FAILED'
46  self.nfail.append(1)
47  self.npass.append(0)
48  else:
49  logline += 'PASSED'
50  self.nfail.append(0)
51  self.npass.append(1)
52  logline += f' - {timelog} - exit: {exitcode}'
53  self.report += logline+'\n\n'
54 
56 
57  def __init__(self, nThrMax=4):
58 
59  self.threadList = []
60  self.maxThreads = nThrMax
61  self.prepare()
62 
63  return
64 
65  def activeThreads(self):
66 
67  nActive = 0
68  for t in self.threadList:
69  if t.is_alive() : nActive += 1
70 
71  return nActive
72 
73  def prepare(self):
74 
75  self.devPath = os.environ['LOCALRT'] + '/src/'
76  self.relPath = self.devPath
77  if 'CMSSW_RELEASE_BASE' in os.environ and (os.environ['CMSSW_RELEASE_BASE'] != ""): self.relPath = os.environ['CMSSW_RELEASE_BASE'] + '/src/'
78 
79  lines = { 'read312RV' : ['cmsRun '+self.file2Path('Utilities/ReleaseScripts/scripts/read312RV_cfg.py')],
80  'fastsim' : ["cmsDriver.py TTbar_8TeV_TuneCUETP8M1_cfi --conditions auto:run1_mc --fast -n 100 --eventcontent AODSIM,DQM --relval 100000,1000 -s GEN,SIM,RECOBEFMIX,DIGI:pdigi_valid,L1,DIGI2RAW,L1Reco,RECO,VALIDATION --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --datatier GEN-SIM-DIGI-RECO,DQMIO --beamspot Realistic8TeVCollision"],
81  'fastsim1' : ["cmsDriver.py TTbar_13TeV_TuneCUETP8M1_cfi --conditions auto:run2_mc_l1stage1 --fast -n 100 --eventcontent AODSIM,DQM --relval 100000,1000 -s GEN,SIM,RECOBEFMIX,DIGI:pdigi_valid,L1,DIGI2RAW,L1Reco,RECO,VALIDATION --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --datatier GEN-SIM-DIGI-RECO,DQMIO --beamspot NominalCollision2015 --era Run2_25ns"],
82  'fastsim2' : ["cmsDriver.py TTbar_13TeV_TuneCUETP8M1_cfi --conditions auto:run2_mc --fast -n 100 --eventcontent AODSIM,DQM --relval 100000,1000 -s GEN,SIM,RECOBEFMIX,DIGI:pdigi_valid,L1,DIGI2RAW,L1Reco,RECO,VALIDATION --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --datatier GEN-SIM-DIGI-RECO,DQMIO --beamspot NominalCollision2015 --era Run2_2016"],
83  'pat1' : ['cmsRun '+self.file2Path('PhysicsTools/PatAlgos/test/IntegrationTest_cfg.py')],
84  }
85 
86  hltTests = {}
87  hltFlag_data = 'realData=True globalTag=@ inputFiles=@'
88  hltFlag_mc = 'realData=False globalTag=@ inputFiles=@'
89  from Configuration.HLT.addOnTestsHLT import addOnTestsHLT
90  hltTestsToAdd = addOnTestsHLT()
91  for key in hltTestsToAdd:
92  if '_data_' in key:
93  hltTests[key] = [hltTestsToAdd[key][0],
94  'cmsRun '+self.file2Path(hltTestsToAdd[key][1])+' '+hltFlag_data,
95  hltTestsToAdd[key][2]]
96  elif '_mc_' in key:
97  hltTests[key] = [hltTestsToAdd[key][0],
98  'cmsRun '+self.file2Path(hltTestsToAdd[key][1])+' '+hltFlag_mc,
99  hltTestsToAdd[key][2]]
100  else:
101  hltTests[key] = [hltTestsToAdd[key][0],
102  'cmsRun '+self.file2Path(hltTestsToAdd[key][1]),
103  hltTestsToAdd[key][2]]
104 
105  self.commands = {}
106  for dirName, command in lines.items():
107  self.commands[dirName] = command
108 
109  for dirName, commandList in hltTests.items():
110  self.commands[dirName] = commandList
111  return
112 
113  def dumpTest(self):
114  print(",".join(self.commands.keys()))
115  return
116 
117  def file2Path(self,rFile):
118 
119  fullPath = self.relPath + rFile
120  if os.path.exists(self.devPath + rFile): fullPath = self.devPath + rFile
121  return fullPath
122 
123  def runTests(self, testList = None):
124 
125  actDir = os.getcwd()
126 
127  if not os.path.exists('addOnTests'):
128  os.makedirs('addOnTests')
129  os.chdir('addOnTests')
130 
131  nfail=0
132  npass=0
133  report=''
134 
135  print('Running in %s thread(s)' % self.maxThreads)
136 
137  if testList:
138  self.commands = {d:c for d,c in self.commands.items() if d in testList}
139  for dirName, command in self.commands.items():
140 
141  # make sure we don't run more than the allowed number of threads:
142  while self.activeThreads() >= self.maxThreads:
143  time.sleep(10)
144  continue
145 
146  print('Preparing to run %s' % str(command))
147  current = testit(dirName, command)
148  self.threadList.append(current)
149  current.start()
150  time.sleep(random.randint(1,5)) # try to avoid race cond by sleeping random amount of time [1,5] sec
151 
152  # wait until all threads are finished
153  while self.activeThreads() > 0:
154  time.sleep(5)
155 
156  # all threads are done now, check status ...
157  for pingle in self.threadList:
158  pingle.join()
159  for f in pingle.nfail: nfail += f
160  for p in pingle.npass: npass += p
161  report += pingle.report
162  print(pingle.report)
163  sys.stdout.flush()
164 
165  reportSumm = '\n %s tests passed, %s failed \n' %(npass,nfail)
166  print(reportSumm)
167 
168  runall_report_name='runall-report.log'
169  runall_report=open(runall_report_name,'w')
170  runall_report.write(report+reportSumm)
171  runall_report.close()
172 
173  # get the logs to the logs dir:
174  print('==> in :', os.getcwd())
175  print(' going to copy log files to logs dir ...')
176  if not os.path.exists('logs'):
177  os.makedirs('logs')
178  for dirName in self.commands:
179  cmd = "for L in `ls "+dirName+"/*.log`; do cp $L logs/cmsDriver-`dirname $L`_`basename $L` ; done"
180  print("going to ",cmd)
181  os.system(cmd)
182 
183  import pickle
184  pickle.dump(self.commands, open('logs/addOnTests.pkl', 'wb'), protocol=2)
185 
186  os.chdir(actDir)
187 
188  return
189 
190  def upload(self, tgtDir):
191 
192  print("in ", os.getcwd())
193 
194  if not os.path.exists(tgtDir):
195  os.makedirs(tgtDir)
196 
197  cmd = 'tar cf - addOnTests.log addOnTests/logs | (cd '+tgtDir+' ; tar xf - ) '
198  try:
199  print('executing: ',cmd)
200  ret = os.system(cmd)
201  if ret != 0:
202  print("ERROR uploading logs:", ret, cmd)
203  except Exception as e:
204  print("EXCEPTION while uploading addOnTest-logs : ", str(e))
205 
206  return
207 
208 
209 def main(argv) :
210 
211  import getopt
212 
213  try:
214  opts, args = getopt.getopt(argv, "dj:t:", ["nproc=", 'uploadDir=', 'tests=','noRun','dump'])
215  except getopt.GetoptError as e:
216  print("unknown option", str(e))
217  sys.exit(2)
218 
219  np = 4
220  uploadDir = None
221  runTests = True
222  testList = None
223  dump = False
224  for opt, arg in opts :
225  if opt in ('-j', "--nproc" ):
226  np=int(arg)
227  if opt in ("--uploadDir", ):
228  uploadDir = arg
229  if opt in ('--noRun', ):
230  runTests = False
231  if opt in ('-d','--dump', ):
232  dump = True
233  if opt in ('-t','--tests', ):
234  testList = arg.split(",")
235 
236  tester = StandardTester(np)
237  if dump:
238  tester.dumpTest()
239  else:
240  if runTests:
241  tester.runTests(testList)
242  if uploadDir:
243  tester.upload(uploadDir)
244  return
245 
246 if __name__ == '__main__' :
247  main(sys.argv[1:])
def file2Path(self, rFile)
Definition: addOnTests.py:117
def upload(self, tgtDir)
Definition: addOnTests.py:190
def main(argv)
Definition: addOnTests.py:209
def __init__(self, dirName, commandList)
Definition: addOnTests.py:17
def __init__(self, nThrMax=4)
Definition: addOnTests.py:57
def runTests(self, testList=None)
Definition: addOnTests.py:123
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
static std::string join(char **cmd)
Definition: RemoteFile.cc:21
Definition: main.py:1
#define str(s)
def run(self)
Definition: addOnTests.py:26