00001
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
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
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
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
00326 print str(err)
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()