CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/CondCore/RegressionTest/python/run_regression.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import sys
00003 import os
00004 import re
00005 import subprocess
00006 import getopt
00007 import random
00008 from xml.dom.minidom import parse, parseString
00009 import CondCore.RegressionTest.common_db    as common_db
00010 import CondCore.RegressionTest.results_db   as results_db
00011 import CondCore.RegressionTest.reference_db as reference_db
00012 
00013 def ParseXML(filename, label):
00014         initSeq = []
00015         mainSeq = []
00016         finalSeq = []
00017         dom = parse(filename)
00018         xml = dom.getElementsByTagName("xml")
00019         foundLabel = False
00020         if xml != None:
00021                 for xm in xml:
00022                         testData = xm.getElementsByTagName("test")
00023                         for it in testData:
00024                                 #print it.toxml()
00025                                 if "name" in  it.attributes.keys():
00026                                         tLabel = str(it.attributes["name"].value)
00027                                         if  tLabel == label:
00028                                                 foundLabel = True
00029                                 if foundLabel == True:
00030                                         inits = it.getElementsByTagName("init")
00031                                         finals = it.getElementsByTagName("final")
00032                                         seqs = it.getElementsByTagName("sequence")
00033                                         for init in inits:
00034                                                 commands = init.getElementsByTagName("command")
00035                                                 for command in commands:
00036                                                         commPars0 = None
00037                                                         commPars1 = None
00038                                                         if "exec" in  command.attributes.keys():
00039                                                                 commPars0 = str(command.attributes["exec"].value)
00040                                                         if "env" in  command.attributes.keys():
00041                                                                 commPars1 = str(command.attributes["env"].value)
00042                                                         initSeq.append((commPars0,commPars1))
00043                                         for seq in seqs:
00044                                                 commands = seq.getElementsByTagName("command")
00045                                                 for command in commands:
00046                                                         commPars0 =  None
00047                                                         commPars1 =  None
00048                                                         commPars2 =  None
00049                                                         if "exec" in  command.attributes.keys():
00050                                                                 commPars0 = str(command.attributes["exec"].value)
00051                                                         if "result" in  command.attributes.keys():
00052                                                                 commPars2 = str(command.attributes["result"].value)
00053                                                         if "env" in  command.attributes.keys():
00054                                                                 commPars1 = str(command.attributes["env"].value)
00055                                                         mainSeq.append( (commPars0,commPars1,commPars2) )
00056                                         for final in finals:
00057                                                 commands = final.getElementsByTagName("command")
00058                                                 for command in commands:
00059                                                         commPars0 =  None
00060                                                         commPars1 =  None
00061                                                         if "exec" in  command.attributes.keys():
00062                                                                 commPars0 = str(command.attributes["exec"].value)
00063                                                         if "env" in  command.attributes.keys():
00064                                                                 commPars1 = str(command.attributes["env"].value)
00065                                                         finalSeq.append( (commPars0,commPars1) )
00066                                 foundLabel = False
00067         return initSeq,mainSeq,finalSeq
00068 
00069 def SetEnv( release, arch, path):
00070         CONNECTION_STRING,USERNAME,PASSWORD,AUTH_PATH = common_db.getDBConnectionParams()
00071         random.seed()
00072         srcPath = os.path.join(path, release,"src")
00073         cmds = """
00074 if [ $RETVAL = 0 ]; then
00075 echo "Setting environment variables for """+release+""" """+arch+""" "
00076 echo "path : """+path+""""
00077         eval pushd """+srcPath+"""
00078         RETVAL=$?
00079         if [ $RETVAL = 0 ]; then
00080                 export SCRAM_ARCH="""+arch+"""
00081                 RETVAL=$?
00082                 if [ $RETVAL = 0 ]; then
00083                         eval `scram runtime -sh`
00084                         RETVAL=$?
00085                         if [ $RETVAL = 0 ]; then
00086                                 export TNS_ADMIN=/afs/cern.ch/project/oracle/admin
00087                                 RETVAL=$?
00088                                 if [ $RETVAL = 0 ]; then
00089                                         eval popd
00090                                         RETVAL=$?
00091                                 fi
00092                         fi
00093                 fi
00094         TRELEASE="""+release+"""
00095         TARCH="""+arch+"""
00096         TPATH="""+path+"""
00097         TMAPNAME="""+release+"""_"""+arch+"""
00098         TMAINDB="""+CONNECTION_STRING+"""
00099         TAUXDB="""+"oracle://cms_orcoff_prep/CMS_COND_WEB"+"""
00100         TUSERNAME="""+USERNAME+"""
00101         TPASSWORD="""+PASSWORD+"""
00102         TTEST=$LOCALRT/test/$TARCH
00103         TBIN=$LOCALRT/bin/$TARCH
00104         TAUTH="""+AUTH_PATH+"""
00105         TSEED="""+str(random.randrange(1, 10))+"""
00106 echo "Environment variables set successfully"
00107         else
00108 echo "Setting environment failed on """+release+""" """+arch+""" return code :  $RETVAL"
00109         fi
00110 fi
00111 echo "----------------------------------------------" 
00112 """
00113         return cmds
00114 
00115 def Command(runStr):
00116         cmds = """
00117 if [ $RETVAL = 0 ]; then
00118 echo "Executing Command """+runStr+""" "
00119 echo "with $TRELEASE $TARCH :"
00120         """+runStr+"""
00121         RETVAL=$?
00122         if [ $RETVAL != 0 ]; then
00123 echo "Task failed on $TRELEASE $TARCH return code :  $RETVAL"
00124         else
00125 echo "Task performed successfully"
00126         fi
00127 fi
00128 """
00129         return cmds
00130 
00131 def RunTest(label,testSeq, release, arch, path, refRelease, refArch, refPath ):
00132         cmds ="""
00133         RETVAL=0
00134 echo "*****************************************************************************************"
00135 echo "Reference release: """+refRelease+""" "
00136 echo "Arch: """+refArch+""" "
00137 echo "Path: """+refPath+""" "
00138 echo "*****************************************************************************************"
00139 """
00140         nr = 0
00141         currEnv = 0
00142         print "-> init"
00143         initSeq = testSeq[0]
00144         mainSeq = testSeq[1]
00145         finalSeq = testSeq[2]
00146         for step in initSeq:
00147                 cmds += """
00148 echo "==============================================="
00149 """
00150                 print step[0]
00151                 if step[1] == "cand" and currEnv != 1:
00152                         cmds += SetEnv(release,arch,path)
00153                         currEnv = 1
00154                 elif step[1] == "ref" and currEnv != 2:
00155                         cmds += SetEnv(refRelease, refArch,refPath)
00156                         currEnv = 2
00157                 cmds +=Command(step[0])
00158         print "-> test sequence"
00159         for step in mainSeq:
00160                 cmds += """
00161 echo "==============================================="
00162 """
00163                 print step[0]
00164                 if step[1] == "cand" and currEnv != 1:
00165                         cmds += SetEnv(release,arch,path)
00166                         currEnv = 1
00167                 elif step[1] == "ref" and currEnv != 2:
00168                         cmds += SetEnv(refRelease, refArch,refPath)
00169                         currEnv = 2
00170                 cmds +=Command(step[0])
00171                 cmds += 'RCODE['+str(nr)+']=$RETVAL'
00172                 nr +=1
00173         print "-> final"
00174         cmds += """
00175         RETVAL=0
00176         """
00177         for step in finalSeq:
00178                 cmds += """
00179 echo "==============================================="
00180 """
00181                 print step[0]
00182                 if step[1] == "cand" and currEnv != 1:
00183                         cmds += SetEnv(release,arch,path)
00184                         currEnv = 1
00185                 elif step[1] == "ref" and currEnv != 2:
00186                         cmds += SetEnv(refRelease, refArch,refPath)
00187                         currEnv = 2
00188                 cmds +=Command(step[0])
00189         cmds += """
00190 echo "==============================================="
00191         echo "Script return code : ${RCODE[1]}"
00192 echo "!L!"""+label+"""!TR!"""+release+"""!TA!"""+arch+"""!RR!"""+refRelease+"""!RA!"""+refArch
00193         for i in range (0, nr):
00194                 cmds+= "!C"+str(i)+"!${RCODE["+str(i)+"]}"
00195         cmds += "\""
00196         return cmds
00197 
00198 def ExecuteCommand( cmdList ):
00199         stdout_value = None
00200         if cmdList != "":
00201                 cmdList+="""
00202         echo "End of test"
00203         echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" """
00204                 pipe = subprocess.Popen(cmdList, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
00205                 stdout_value = pipe.communicate()[0]
00206         return stdout_value
00207 
00208 class RegressionTest:
00209         
00210     def __init__( self, conn ):
00211         self.resDb = results_db.ResultsDB( conn )
00212         self.refDb = reference_db.ReferenceDB( conn )
00213         self.label = None
00214         self.n_res = 0
00215         self.resTags = None
00216         self.out_value = None
00217 
00218     def runOnDb(self, label, release, arch, path):
00219         relID = reference_db.ExtractID(release)
00220         print 'Running test "'+label+'" on rel='+release+' arch='+arch+' from path= '+path
00221         cmds = """
00222 echo ""
00223 echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
00224 echo "Candidate release: """+release+""" "
00225 echo "Arch: """+arch+""" "
00226 echo "Path: """+path+""" "
00227 echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
00228 """
00229         testSeq = ParseXML("sequences.xml", label)
00230         self.n_res = len(testSeq[1])
00231         if(self.n_res == 0):
00232             print "Error : no test sequence found for label %s"%label
00233             return 0
00234         self.resTags = []
00235         for step in testSeq[1]:
00236                 self.resTags.append( step[2] )
00237         releases = self.refDb.listReleases( relID )
00238         for rel in releases:
00239                 cmd  = RunTest( label,testSeq, release, arch, path, rel[0], rel[1], rel[2])
00240                 cmds += cmd
00241         self.out_value =  ExecuteCommand( cmds )
00242         self.label = label
00243         return len(releases)
00244 
00245     def runOnReference(self, label, release, arch, path, refRelease, refArch, refPath):
00246         relID = reference_db.ExtractID(release)
00247         print "Testing "+release+" "+arch+" from path: "+path
00248         curs = conn.cursor()
00249         cmds = """
00250 echo ""
00251 echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
00252 echo "Candidate release: """+release+""" "
00253 echo "Arch: """+arch+""" "
00254 echo "Path: """+path+""" "
00255 echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
00256 """
00257         testSeq = ParseXML("sequences.xml", label)
00258         self.n_res = len( testSeq[1] )
00259         if(self.n_res == 0):
00260                 print "Error : no test sequence found for label %s"%label
00261                 return 0
00262         self.resTags = []
00263         for step in testSeq[1]:
00264                 self.resTags.append( step[2] )
00265         cmd = RunTest(label,testSeq, release, arch, path, refRelease, refArch, refPath)
00266         cmds += cmd
00267         self.out_value =  ExecuteCommand( cmds )
00268         self.label = label
00269         return 1
00270 
00271     def finalize( self, writeFlag ):
00272 
00273         reStr = "\!L\!([^!]+)\!TR\!([^!]+)\!TA\!([^!]+)\!RR\!([^!]+)\!RA\!([^!]+)"
00274         for i in range (0, self.n_res):
00275                 reStr +=  "\!C"+str(i)+"\!(\d+)"
00276         #print 'restr1=',reStr
00277 
00278         pattern = re.compile(reStr)
00279         matching = pattern.findall(self.out_value)
00280         stdoutMod = pattern.sub("", self.out_value)
00281         timeStamp = self.resDb.getDate()
00282         stat = "SUCCESS"
00283         runID = 0
00284         if( writeFlag ):
00285                 runID = self.resDb.getNewRunId()
00286         for match in matching:
00287                 #print match
00288                 if( writeFlag):
00289                         self.resDb.writeResult(runID, timeStamp, match,self.resTags)
00290                 for i in range(5, len(match)):
00291                         if( match[i] != str(0) ):
00292                                 stat = "FAILURE"
00293         print stdoutMod
00294         if( writeFlag ):
00295                 self.resDb.addResultLog(runID, stdoutMod)
00296         print "Test '%s' runID=%d" %(self.label, runID)
00297         print "Exit status=%s" %stat
00298         print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
00299 
00300 def CmdUsage():
00301         print "Command line arguments :"
00302         print "-F (--full) -t [test_label] -r [release] -a [arch] -p [path]: runs the full test. " 
00303         print "-S (--self) -t [test_label] -r [release] -a [arch] -p [path]: runs the self test. " 
00304         print "-R [ref_release] -A [ref_arch] -P [ref_path]  -t [test_label] -r [release] -a [arch] -p [path]: runs the test against the specified ref release. "
00305         print "   optional flag -w: write the test result in the database. "
00306         
00307 def CheckPath (release, arch, path):
00308         if(os.path.exists(path)):
00309                 if(os.path.exists(os.path.join(path, release))):
00310                         if(os.path.exists(os.path.join(path, release, "test", arch))):
00311                                 return True
00312                         else:
00313                                 print "Architecture not found"
00314                                 return False
00315                 else:
00316                         print "Release not found"
00317                         return False
00318         else:
00319                 print "Path not found"
00320                 return False
00321         
00322 try:
00323         opts, args = getopt.getopt(sys.argv[1:], "FSR:A:P:t:r:a:p:hw", ['full', 'self', 'help'])
00324 except getopt.GetoptError, err:
00325         # print help information and exit:
00326         print str(err) # will print something like "option -a not recognized"
00327         CmdUsage()
00328         sys.exit(2)
00329 RELEASE = None
00330 ARCH = None
00331 PATH = None
00332 REF_RELEASE = None
00333 REF_ARCH = None
00334 REF_PATH = None
00335 LABEL = None
00336 fflag = False
00337 sflag = False
00338 wflag = False
00339 for o, a in opts:
00340         if o in ("-F", "--full"):
00341                 fflag = True
00342         elif o in ("-S", "--self"):
00343                 sflag = True
00344         elif o == "-R":
00345                 REF_RELEASE = a
00346         elif o == "-A":
00347                 REF_ARCH = a
00348         elif o == "-P":
00349                 REF_PATH = a
00350         elif o == "-t":
00351                 LABEL = a
00352         elif o == "-r":
00353                 RELEASE = a
00354         elif o == "-a":
00355                 ARCH = a
00356         elif o == "-p":
00357                 PATH = a
00358         elif o == "-w":
00359                 wflag = True
00360         elif o in ("-h", "--help"):
00361                 CmdUsage()
00362                 sys.exit(2)
00363         else:
00364                 assert False, "unhandled option"
00365 if( fflag == False and sflag == False and REF_RELEASE == None ):
00366         print "Error: missing main run option."
00367 else:
00368         okPar = True
00369         if ( LABEL == None ):
00370                 okPar = False
00371                 print "Error: missing -l (label) parameter"
00372         if(RELEASE == None ):
00373                 okPar = False
00374                 print "Error: missing -r (release) parameter"
00375         if( ARCH == None ):
00376                 okPar = False
00377                 print "Error: missing -a (architecture) parameter"
00378         if( PATH == None):
00379                 okPar = False
00380                 print "Error: missing -p (path) parameter"
00381         if(CheckPath(RELEASE, ARCH, PATH) == False):
00382                 okPar = False
00383                 print "Error: bad path specified for the release"
00384         if( okPar == True ):
00385                 conn = common_db.createDBConnection()
00386                 test = RegressionTest( conn )
00387                 done = False
00388                 ret = 0
00389                 if( fflag == True and done==False ):
00390                     ret = test.runOnDb(LABEL, RELEASE, ARCH, PATH)
00391                     done = True
00392                 if( sflag == True and done==False ):
00393                     ret = test.runOnReference(LABEL, RELEASE, ARCH, PATH, RELEASE, ARCH, PATH)
00394                     done = True
00395                 if( REF_RELEASE != None and done==False ):
00396                     if( REF_ARCH == None ):
00397                         okPar = False
00398                         print "Error: missing -A (ref architecture) parameter"
00399                     if( REF_PATH == None):
00400                         okPar = False
00401                         print "Error: missing -P (ref path) parameter"
00402                     if(CheckPath(REF_RELEASE, REF_ARCH, REF_PATH) == False):
00403                         okPar = False
00404                         print "Error: bad path specified for the ref release"
00405                     if( okPar == True ):
00406                         ret = test.runOnReference(LABEL, RELEASE, ARCH, PATH, REF_RELEASE, REF_ARCH, REF_PATH)
00407                         done = True
00408                 if ( done == True and ret>0  ):
00409                         test.finalize( wflag )
00410                 conn.close()