1*29921a8fSScott Kruger#!/usr/bin/env python 2*29921a8fSScott Kruger 3*29921a8fSScott Krugerimport os,shutil, string, re 4*29921a8fSScott Krugerfrom distutils.sysconfig import parse_makefile 5*29921a8fSScott Krugerimport sys 6*29921a8fSScott Krugerimport logging 7*29921a8fSScott Krugerimport types 8*29921a8fSScott Krugersys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) 9*29921a8fSScott Krugerfrom cmakegen import Mistakes, stripsplit, AUTODIRS, SKIPDIRS 10*29921a8fSScott Krugerfrom cmakegen import defaultdict # collections.defaultdict, with fallback for python-2.4 11*29921a8fSScott Krugerfrom gmakegen import * 12*29921a8fSScott Kruger 13*29921a8fSScott Krugerimport inspect 14*29921a8fSScott Krugerthisscriptdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 15*29921a8fSScott Krugersys.path.insert(0,thisscriptdir) 16*29921a8fSScott Krugerimport testparse 17*29921a8fSScott Krugerimport example_template 18*29921a8fSScott Kruger 19*29921a8fSScott Krugerclass generateExamples(Petsc): 20*29921a8fSScott Kruger """ 21*29921a8fSScott Kruger gmakegen.py has basic structure for finding the files, writing out 22*29921a8fSScott Kruger the dependencies, etc. 23*29921a8fSScott Kruger """ 24*29921a8fSScott Kruger def __init__(self,petsc_dir=None, petsc_arch=None, verbose=False, single_ex=False): 25*29921a8fSScott Kruger super(generateExamples, self).__init__(petsc_dir=None, petsc_arch=None, verbose=False) 26*29921a8fSScott Kruger 27*29921a8fSScott Kruger self.single_ex=single_ex 28*29921a8fSScott Kruger self.arch_dir=os.path.join(self.petsc_dir,self.petsc_arch) 29*29921a8fSScott Kruger self.ptNaming=True 30*29921a8fSScott Kruger # Whether to write out a useful debugging 31*29921a8fSScott Kruger #if verbose: self.summarize=True 32*29921a8fSScott Kruger self.summarize=True 33*29921a8fSScott Kruger 34*29921a8fSScott Kruger # For help in setting the requirements 35*29921a8fSScott Kruger self.precision_types="single double quad int32".split() 36*29921a8fSScott Kruger self.integer_types="int32 int64".split() 37*29921a8fSScott Kruger self.languages="fortran cuda cxx".split() # Always requires C so do not list 38*29921a8fSScott Kruger 39*29921a8fSScott Kruger # Things that are not test 40*29921a8fSScott Kruger self.buildkeys=testparse.buildkeys 41*29921a8fSScott Kruger 42*29921a8fSScott Kruger # Adding a dictionary for storing sources, objects, and tests 43*29921a8fSScott Kruger # to make building the dependency tree easier 44*29921a8fSScott Kruger self.sources={} 45*29921a8fSScott Kruger self.objects={} 46*29921a8fSScott Kruger self.tests={} 47*29921a8fSScott Kruger for pkg in PKGS: 48*29921a8fSScott Kruger self.sources[pkg]={} 49*29921a8fSScott Kruger self.objects[pkg]=[] 50*29921a8fSScott Kruger self.tests[pkg]={} 51*29921a8fSScott Kruger for lang in LANGS: 52*29921a8fSScott Kruger self.sources[pkg][lang]={} 53*29921a8fSScott Kruger self.sources[pkg][lang]['srcs']=[] 54*29921a8fSScott Kruger self.tests[pkg][lang]={} 55*29921a8fSScott Kruger 56*29921a8fSScott Kruger # Copy petsc tests harness script 57*29921a8fSScott Kruger harness_file=os.path.join(self.petsc_dir,"config","petsc_harness.sh") 58*29921a8fSScott Kruger reports_file=os.path.join(self.petsc_dir,"config","report_tests.sh") 59*29921a8fSScott Kruger self.testroot_dir=os.path.join(self.arch_dir,"tests") 60*29921a8fSScott Kruger if not os.path.isdir(self.testroot_dir): os.makedirs(self.testroot_dir) 61*29921a8fSScott Kruger shutil.copy(harness_file,self.testroot_dir) 62*29921a8fSScott Kruger shutil.copy(reports_file,self.testroot_dir) 63*29921a8fSScott Kruger 64*29921a8fSScott Kruger return 65*29921a8fSScott Kruger 66*29921a8fSScott Kruger def nameSpace(self,srcfile,srcdir): 67*29921a8fSScott Kruger """ 68*29921a8fSScott Kruger Because the scripts have a non-unique naming, the pretty-printing 69*29921a8fSScott Kruger needs to convey the srcdir and srcfile. There are two ways of doing this. 70*29921a8fSScott Kruger """ 71*29921a8fSScott Kruger if self.ptNaming: 72*29921a8fSScott Kruger cdir=srcdir.split('src')[1].lstrip("/").rstrip("/") 73*29921a8fSScott Kruger prefix=cdir.replace('/examples/','_').replace("/","_")+"-" 74*29921a8fSScott Kruger nameString=prefix+srcfile 75*29921a8fSScott Kruger else: 76*29921a8fSScott Kruger #nameString=srcdir+": "+srcfile 77*29921a8fSScott Kruger nameString=srcfile 78*29921a8fSScott Kruger return nameString 79*29921a8fSScott Kruger 80*29921a8fSScott Kruger def getLanguage(self,srcfile): 81*29921a8fSScott Kruger """ 82*29921a8fSScott Kruger Based on the source, determine associated language as found in gmakegen.LANGS 83*29921a8fSScott Kruger Can we just return srcext[1:\] now? 84*29921a8fSScott Kruger """ 85*29921a8fSScott Kruger langReq=None 86*29921a8fSScott Kruger srcext=os.path.splitext(srcfile)[-1] 87*29921a8fSScott Kruger if srcext in ".F90".split(): langReq="F90" 88*29921a8fSScott Kruger if srcext in ".F".split(): langReq="F" 89*29921a8fSScott Kruger if srcext in ".cxx".split(): langReq="cxx" 90*29921a8fSScott Kruger if srcext == ".cu": langReq="cu" 91*29921a8fSScott Kruger if srcext == ".c": langReq="c" 92*29921a8fSScott Kruger if not langReq: print "ERROR: ", srcext, srcfile 93*29921a8fSScott Kruger return langReq 94*29921a8fSScott Kruger 95*29921a8fSScott Kruger def getArgLabel(self,testDict): 96*29921a8fSScott Kruger """ 97*29921a8fSScott Kruger In all of the arguments in the test dictionary, create a simple 98*29921a8fSScott Kruger string for searching within the makefile system. For simplicity in 99*29921a8fSScott Kruger search, remove "-", for strings, etc. 100*29921a8fSScott Kruger Also, concatenate the arg commands 101*29921a8fSScott Kruger For now, ignore nsize -- seems hard to search for anyway 102*29921a8fSScott Kruger """ 103*29921a8fSScott Kruger # Collect all of the args associated with a test 104*29921a8fSScott Kruger argStr=("" if not testDict.has_key('args') else testDict['args']) 105*29921a8fSScott Kruger if testDict.has_key('subtests'): 106*29921a8fSScott Kruger for stest in testDict["subtests"]: 107*29921a8fSScott Kruger sd=testDict[stest] 108*29921a8fSScott Kruger argStr=argStr+("" if not sd.has_key('args') else sd['args']) 109*29921a8fSScott Kruger 110*29921a8fSScott Kruger # Now go through and cleanup 111*29921a8fSScott Kruger argStr=re.sub('{{(.*?)}}',"",argStr) 112*29921a8fSScott Kruger argStr=re.sub('-'," ",argStr) 113*29921a8fSScott Kruger for digit in string.digits: argStr=re.sub(digit," ",argStr) 114*29921a8fSScott Kruger argStr=re.sub("\.","",argStr) 115*29921a8fSScott Kruger argStr=re.sub(",","",argStr) 116*29921a8fSScott Kruger argStr=re.sub('\+',' ',argStr) 117*29921a8fSScott Kruger argStr=re.sub(' +',' ',argStr) # Remove repeated white space 118*29921a8fSScott Kruger return argStr.strip() 119*29921a8fSScott Kruger 120*29921a8fSScott Kruger def addToSources(self,exfile,root,srcDict): 121*29921a8fSScott Kruger """ 122*29921a8fSScott Kruger Put into data structure that allows easy generation of makefile 123*29921a8fSScott Kruger """ 124*29921a8fSScott Kruger pkg=self.relpath(self.petsc_dir,root).split("/")[1] 125*29921a8fSScott Kruger fullfile=os.path.join(root,exfile) 126*29921a8fSScott Kruger relpfile=self.relpath(self.petsc_dir,fullfile) 127*29921a8fSScott Kruger lang=self.getLanguage(exfile) 128*29921a8fSScott Kruger self.sources[pkg][lang]['srcs'].append(relpfile) 129*29921a8fSScott Kruger if srcDict.has_key('depends'): 130*29921a8fSScott Kruger depSrc=srcDict['depends'] 131*29921a8fSScott Kruger depObj=os.path.splitext(depSrc)[0]+".o" 132*29921a8fSScott Kruger self.sources[pkg][lang][exfile]=depObj 133*29921a8fSScott Kruger 134*29921a8fSScott Kruger # In gmakefile, ${TESTDIR} var specifies the object compilation 135*29921a8fSScott Kruger testsdir=self.relpath(self.petsc_dir,root)+"/" 136*29921a8fSScott Kruger objfile="${TESTDIR}/"+testsdir+os.path.splitext(exfile)[0]+".o" 137*29921a8fSScott Kruger self.objects[pkg].append(objfile) 138*29921a8fSScott Kruger return 139*29921a8fSScott Kruger 140*29921a8fSScott Kruger def addToTests(self,test,root,exfile,execname,testDict): 141*29921a8fSScott Kruger """ 142*29921a8fSScott Kruger Put into data structure that allows easy generation of makefile 143*29921a8fSScott Kruger Organized by languages to allow testing of languages 144*29921a8fSScott Kruger """ 145*29921a8fSScott Kruger pkg=self.relpath(self.petsc_dir,root).split("/")[1] 146*29921a8fSScott Kruger #nmtest=self.nameSpace(test,root) 147*29921a8fSScott Kruger rpath=self.relpath(self.petsc_dir,root) 148*29921a8fSScott Kruger nmtest=os.path.join(rpath,test) 149*29921a8fSScott Kruger lang=self.getLanguage(exfile) 150*29921a8fSScott Kruger self.tests[pkg][lang][nmtest]={} 151*29921a8fSScott Kruger self.tests[pkg][lang][nmtest]['exfile']=os.path.join(rpath,exfile) 152*29921a8fSScott Kruger self.tests[pkg][lang][nmtest]['exec']=execname 153*29921a8fSScott Kruger self.tests[pkg][lang][nmtest]['argLabel']=self.getArgLabel(testDict) 154*29921a8fSScott Kruger return 155*29921a8fSScott Kruger 156*29921a8fSScott Kruger def getFor(self,subst,i,j): 157*29921a8fSScott Kruger """ 158*29921a8fSScott Kruger Get the for and done lines 159*29921a8fSScott Kruger """ 160*29921a8fSScott Kruger forlines="" 161*29921a8fSScott Kruger donlines="" 162*29921a8fSScott Kruger indent=" " 163*29921a8fSScott Kruger nsizeStr=subst['nsize'] 164*29921a8fSScott Kruger for loop in re.findall('{{(.*?)}}',subst['nsize']): 165*29921a8fSScott Kruger lindex=string.ascii_lowercase[i] 166*29921a8fSScott Kruger forline=indent*j+"for "+lindex+" in '"+loop+"'; do" 167*29921a8fSScott Kruger nsizeStr=re.sub("{{"+loop+"}}","${"+lindex+"}",nsizeStr) 168*29921a8fSScott Kruger donline=indent*j+"done" 169*29921a8fSScott Kruger forlines=forlines+forline+"\n" 170*29921a8fSScott Kruger donlines=donlines+donline+"\n" 171*29921a8fSScott Kruger i=i+1 172*29921a8fSScott Kruger j=j+1 173*29921a8fSScott Kruger subst['nsize']=nsizeStr 174*29921a8fSScott Kruger argStr=subst['args'] 175*29921a8fSScott Kruger for loop in re.findall('{{(.*?)}}',subst['args']): 176*29921a8fSScott Kruger lindex=string.ascii_lowercase[i] 177*29921a8fSScott Kruger forline=indent*j+"for "+lindex+" in '"+loop+"'; do" 178*29921a8fSScott Kruger argStr=re.sub("{{"+loop+"}}","${"+lindex+"}",argStr) 179*29921a8fSScott Kruger donline=indent*j+"done" 180*29921a8fSScott Kruger forlines=forlines+forline+"\n" 181*29921a8fSScott Kruger donlines=donlines+donline+"\n" 182*29921a8fSScott Kruger i=i+1 183*29921a8fSScott Kruger j=j+1 184*29921a8fSScott Kruger subst['args']=argStr 185*29921a8fSScott Kruger 186*29921a8fSScott Kruger # The do lines have reverse order with respect to indentation 187*29921a8fSScott Kruger dl=donlines.rstrip("\n").split("\n") 188*29921a8fSScott Kruger dl.reverse() 189*29921a8fSScott Kruger donlines="\n".join(dl)+"\n" 190*29921a8fSScott Kruger 191*29921a8fSScott Kruger return forlines,donlines,i,j 192*29921a8fSScott Kruger 193*29921a8fSScott Kruger 194*29921a8fSScott Kruger def getExecname(self,exfile,root): 195*29921a8fSScott Kruger """ 196*29921a8fSScott Kruger Generate bash script using template found next to this file. 197*29921a8fSScott Kruger This file is read in at constructor time to avoid file I/O 198*29921a8fSScott Kruger """ 199*29921a8fSScott Kruger rpath=self.relpath(self.petsc_dir,root) 200*29921a8fSScott Kruger if self.single_ex: 201*29921a8fSScott Kruger execname=rpath.split("/")[1]+"-ex" 202*29921a8fSScott Kruger else: 203*29921a8fSScott Kruger execname=os.path.splitext(exfile)[0] 204*29921a8fSScott Kruger return execname 205*29921a8fSScott Kruger 206*29921a8fSScott Kruger def getSubstVars(self,testDict,rpath,testname): 207*29921a8fSScott Kruger """ 208*29921a8fSScott Kruger Create a dictionary with all of the variables that get substituted 209*29921a8fSScott Kruger into the template commands found in example_template.py 210*29921a8fSScott Kruger TODO: Cleanup 211*29921a8fSScott Kruger """ 212*29921a8fSScott Kruger subst={} 213*29921a8fSScott Kruger # Handle defaults 214*29921a8fSScott Kruger if not testDict.has_key('nsize'): testDict['nsize']=1 215*29921a8fSScott Kruger if not testDict.has_key('filter'): testDict['filter']="" 216*29921a8fSScott Kruger if not testDict.has_key('args'): testDict['args']="" 217*29921a8fSScott Kruger defroot=(re.sub("run","",testname) if testname.startswith("run") else testname) 218*29921a8fSScott Kruger if not testDict.has_key('redirect_file'): testDict['redirect_file']=defroot+".tmp" 219*29921a8fSScott Kruger if not testDict.has_key('output_file'): testDict['output_file']="output/"+defroot+".out" 220*29921a8fSScott Kruger 221*29921a8fSScott Kruger # Setup the variables in template_string that need to be substituted 222*29921a8fSScott Kruger subst['srcdir']=os.path.join(self.petsc_dir,rpath) 223*29921a8fSScott Kruger subst['label']=self.nameSpace(defroot,subst['srcdir']) 224*29921a8fSScott Kruger subst['output_file']=os.path.join(subst['srcdir'],testDict['output_file']) 225*29921a8fSScott Kruger subst['exec']="../"+testDict['execname'] 226*29921a8fSScott Kruger subst['redirect_file']=testDict['redirect_file'] 227*29921a8fSScott Kruger subst['filter']=testDict['filter'] 228*29921a8fSScott Kruger subst['testroot']=self.testroot_dir 229*29921a8fSScott Kruger subst['testname']=testname 230*29921a8fSScott Kruger 231*29921a8fSScott Kruger # Be careful with this 232*29921a8fSScott Kruger if testDict.has_key('command'): subst['command']=testDict['command'] 233*29921a8fSScott Kruger 234*29921a8fSScott Kruger # These can have for loops and are treated separately later 235*29921a8fSScott Kruger if testDict.has_key('nsize'): subst['nsize']=str(testDict['nsize']) 236*29921a8fSScott Kruger if testDict.has_key('args'): subst['args']=testDict['args'] 237*29921a8fSScott Kruger 238*29921a8fSScott Kruger #Conf vars 239*29921a8fSScott Kruger subst['mpiexec']=self.conf['MPIEXEC'] # make sure PETSC_DIR is defined! 240*29921a8fSScott Kruger subst['diff']=self.conf['DIFF'] 241*29921a8fSScott Kruger subst['rm']=self.conf['RM'] 242*29921a8fSScott Kruger subst['grep']=self.conf['GREP'] 243*29921a8fSScott Kruger 244*29921a8fSScott Kruger return subst 245*29921a8fSScott Kruger 246*29921a8fSScott Kruger def getCmds(self,subst,i): 247*29921a8fSScott Kruger """ 248*29921a8fSScott Kruger Generate bash script using template found next to this file. 249*29921a8fSScott Kruger This file is read in at constructor time to avoid file I/O 250*29921a8fSScott Kruger """ 251*29921a8fSScott Kruger indent=" " 252*29921a8fSScott Kruger nindent=i # the start and has to be consistent with below 253*29921a8fSScott Kruger cmdLines="" 254*29921a8fSScott Kruger # MPI is the default -- but we have a few odd commands 255*29921a8fSScott Kruger if not subst.has_key('command'): 256*29921a8fSScott Kruger cmd=indent*nindent+self._substVars(subst,example_template.mpitest) 257*29921a8fSScott Kruger else: 258*29921a8fSScott Kruger cmd=indent*nindent+self._substVars(subst,example_template.commandtest) 259*29921a8fSScott Kruger cmdLines=cmdLines+cmd+"\n\n" 260*29921a8fSScott Kruger 261*29921a8fSScott Kruger cmd=indent*nindent+self._substVars(subst,example_template.difftest) 262*29921a8fSScott Kruger cmdLines=cmdLines+cmd+"\n" 263*29921a8fSScott Kruger return cmdLines 264*29921a8fSScott Kruger 265*29921a8fSScott Kruger def _substVars(self,subst,origStr): 266*29921a8fSScott Kruger """ 267*29921a8fSScott Kruger Substitute varial 268*29921a8fSScott Kruger """ 269*29921a8fSScott Kruger Str=origStr 270*29921a8fSScott Kruger for subkey in subst: 271*29921a8fSScott Kruger if type(subst[subkey])!=types.StringType: continue 272*29921a8fSScott Kruger patt="@"+subkey.upper()+"@" 273*29921a8fSScott Kruger Str=re.sub(patt,subst[subkey],Str) 274*29921a8fSScott Kruger return Str 275*29921a8fSScott Kruger 276*29921a8fSScott Kruger def genRunScript(self,testname,root,isRun,srcDict): 277*29921a8fSScott Kruger """ 278*29921a8fSScott Kruger Generate bash script using template found next to this file. 279*29921a8fSScott Kruger This file is read in at constructor time to avoid file I/O 280*29921a8fSScott Kruger """ 281*29921a8fSScott Kruger # runscript_dir directory has to be consistent with gmakefile 282*29921a8fSScott Kruger testDict=srcDict[testname] 283*29921a8fSScott Kruger rpath=self.relpath(self.petsc_dir,root) 284*29921a8fSScott Kruger runscript_dir=os.path.join(self.testroot_dir,rpath) 285*29921a8fSScott Kruger if not os.path.isdir(runscript_dir): os.makedirs(runscript_dir) 286*29921a8fSScott Kruger fh=open(os.path.join(runscript_dir,testname+".sh"),"w") 287*29921a8fSScott Kruger petscvarfile=os.path.join(self.arch_dir,'lib','petsc','conf','petscvariables') 288*29921a8fSScott Kruger 289*29921a8fSScott Kruger subst=self.getSubstVars(testDict,rpath,testname) 290*29921a8fSScott Kruger 291*29921a8fSScott Kruger # Now substitute the key variables into the header and footer 292*29921a8fSScott Kruger header=self._substVars(subst,example_template.header) 293*29921a8fSScott Kruger footer=re.sub('@TESTSROOT@',subst['testroot'],example_template.footer) 294*29921a8fSScott Kruger 295*29921a8fSScott Kruger # Start writing the file 296*29921a8fSScott Kruger fh.write(header+"\n") 297*29921a8fSScott Kruger 298*29921a8fSScott Kruger # If there is a TODO or a SKIP then we do it before writing out the 299*29921a8fSScott Kruger # rest of the command (which is useful for working on the test) 300*29921a8fSScott Kruger # SKIP and TODO can be for the source file or for the runs 301*29921a8fSScott Kruger if srcDict.has_key("SKIP") or srcDict.has_key("TODO"): 302*29921a8fSScott Kruger if srcDict.has_key("TODO"): 303*29921a8fSScott Kruger todo=re.sub("@TODOCOMMENT@",srcDict['TODO'],example_template.todoline) 304*29921a8fSScott Kruger fh.write(todo+"\ntotal=1; todo=1\n") 305*29921a8fSScott Kruger fh.write(footer+"\n") 306*29921a8fSScott Kruger fh.write("exit\n\n\n") 307*29921a8fSScott Kruger elif srcDict.has_key("SKIP") or srcDict.has_key("TODO"): 308*29921a8fSScott Kruger skip=re.sub("@SKIPCOMMENT@",srcDict['SKIP'],example_template.skipline) 309*29921a8fSScott Kruger fh.write(skip+"\ntotal=1; skip=1\n") 310*29921a8fSScott Kruger fh.write(footer+"\n") 311*29921a8fSScott Kruger fh.write("exit\n\n\n") 312*29921a8fSScott Kruger elif not isRun: 313*29921a8fSScott Kruger skip=re.sub("@SKIPCOMMENT@",testDict['SKIP'],example_template.skipline) 314*29921a8fSScott Kruger fh.write(skip+"\ntotal=1; skip=1\n") 315*29921a8fSScott Kruger fh.write(footer+"\n") 316*29921a8fSScott Kruger fh.write("exit\n\n\n") 317*29921a8fSScott Kruger elif testDict.has_key('TODO'): 318*29921a8fSScott Kruger todo=re.sub("@TODOCOMMENT@",testDict['TODO'],example_template.todoline) 319*29921a8fSScott Kruger fh.write(todo+"\ntotal=1; todo=1\n") 320*29921a8fSScott Kruger fh.write(footer+"\n") 321*29921a8fSScott Kruger fh.write("exit\n\n\n") 322*29921a8fSScott Kruger 323*29921a8fSScott Kruger # Need to handle loops 324*29921a8fSScott Kruger i=8 # for loop counters 325*29921a8fSScott Kruger j=0 # for indentation 326*29921a8fSScott Kruger 327*29921a8fSScott Kruger doForP=False 328*29921a8fSScott Kruger if "{{" in subst['args']+subst['nsize']: 329*29921a8fSScott Kruger doForP=True 330*29921a8fSScott Kruger flinesP,dlinesP,i,j=self.getFor(subst,i,j) 331*29921a8fSScott Kruger fh.write(flinesP+"\n") 332*29921a8fSScott Kruger 333*29921a8fSScott Kruger # Subtests are special 334*29921a8fSScott Kruger if testDict.has_key("subtests"): 335*29921a8fSScott Kruger substP=subst # Subtests can inherit args but be careful 336*29921a8fSScott Kruger if not substP.has_key("arg"): substP["arg"]="" 337*29921a8fSScott Kruger jorig=j 338*29921a8fSScott Kruger for stest in testDict["subtests"]: 339*29921a8fSScott Kruger j=jorig 340*29921a8fSScott Kruger subst=substP 341*29921a8fSScott Kruger subst.update(testDict[stest]) 342*29921a8fSScott Kruger subst['nsize']=str(subst['nsize']) 343*29921a8fSScott Kruger if not testDict[stest].has_key('args'): testDict[stest]['args']="" 344*29921a8fSScott Kruger subst['args']=substP['args']+testDict[stest]['args'] 345*29921a8fSScott Kruger doFor=False 346*29921a8fSScott Kruger if "{{" in subst['args']+subst['nsize']: 347*29921a8fSScott Kruger doFor=True 348*29921a8fSScott Kruger flines,dlines,i,j=self.getFor(subst,i,j) 349*29921a8fSScott Kruger fh.write(flines+"\n") 350*29921a8fSScott Kruger fh.write(self.getCmds(subst,j)+"\n") 351*29921a8fSScott Kruger if doFor: fh.write(dlines+"\n") 352*29921a8fSScott Kruger else: 353*29921a8fSScott Kruger fh.write(self.getCmds(subst,j)+"\n") 354*29921a8fSScott Kruger if doForP: fh.write(dlinesP+"\n") 355*29921a8fSScott Kruger 356*29921a8fSScott Kruger fh.write(footer+"\n") 357*29921a8fSScott Kruger os.chmod(os.path.join(runscript_dir,testname+".sh"),0777) 358*29921a8fSScott Kruger return 359*29921a8fSScott Kruger 360*29921a8fSScott Kruger def genScriptsAndInfo(self,exfile,root,srcDict): 361*29921a8fSScott Kruger """ 362*29921a8fSScott Kruger Generate scripts from the source file, determine if built, etc. 363*29921a8fSScott Kruger For every test in the exfile with info in the srcDict: 364*29921a8fSScott Kruger 1. Determine if it needs to be run for this arch 365*29921a8fSScott Kruger 2. Generate the script 366*29921a8fSScott Kruger 3. Generate the data needed to write out the makefile in a 367*29921a8fSScott Kruger convenient way 368*29921a8fSScott Kruger All tests are *always* run, but some may be SKIP'd per the TAP standard 369*29921a8fSScott Kruger """ 370*29921a8fSScott Kruger debug=False 371*29921a8fSScott Kruger fileIsTested=False 372*29921a8fSScott Kruger execname=self.getExecname(exfile,root) 373*29921a8fSScott Kruger isBuilt=self._isBuilt(exfile,srcDict) 374*29921a8fSScott Kruger for test in srcDict: 375*29921a8fSScott Kruger if test in self.buildkeys: continue 376*29921a8fSScott Kruger if debug: print self.nameSpace(exfile,root), test 377*29921a8fSScott Kruger srcDict[test]['execname']=execname # Convenience in generating scripts 378*29921a8fSScott Kruger isRun=self._isRun(srcDict[test]) 379*29921a8fSScott Kruger self.genRunScript(test,root,isRun,srcDict) 380*29921a8fSScott Kruger srcDict[test]['isrun']=isRun 381*29921a8fSScott Kruger if isRun: fileIsTested=True 382*29921a8fSScott Kruger self.addToTests(test,root,exfile,execname,srcDict[test]) 383*29921a8fSScott Kruger 384*29921a8fSScott Kruger # This adds to datastructure for building deps 385*29921a8fSScott Kruger if fileIsTested and isBuilt: self.addToSources(exfile,root,srcDict) 386*29921a8fSScott Kruger #print self.nameSpace(exfile,root), fileIsTested 387*29921a8fSScott Kruger return 388*29921a8fSScott Kruger 389*29921a8fSScott Kruger def _isBuilt(self,exfile,srcDict): 390*29921a8fSScott Kruger """ 391*29921a8fSScott Kruger Determine if this file should be built. 392*29921a8fSScott Kruger """ 393*29921a8fSScott Kruger # Get the language based on file extension 394*29921a8fSScott Kruger lang=self.getLanguage(exfile) 395*29921a8fSScott Kruger if lang=="f" and not self.have_fortran: 396*29921a8fSScott Kruger srcDict["SKIP"]="Fortran required for this test" 397*29921a8fSScott Kruger return False 398*29921a8fSScott Kruger if lang=="cu" and not self.conf.has_key('PETSC_HAVE_CUDA'): 399*29921a8fSScott Kruger srcDict["SKIP"]="CUDA required for this test" 400*29921a8fSScott Kruger return False 401*29921a8fSScott Kruger if lang=="cxx" and not self.conf.has_key('PETSC_HAVE_CXX'): 402*29921a8fSScott Kruger srcDict["SKIP"]="C++ required for this test" 403*29921a8fSScott Kruger return False 404*29921a8fSScott Kruger 405*29921a8fSScott Kruger # Deprecated source files 406*29921a8fSScott Kruger if srcDict.has_key("TODO"): return False 407*29921a8fSScott Kruger 408*29921a8fSScott Kruger # isRun can work with srcDict to handle the requires 409*29921a8fSScott Kruger if srcDict.has_key("requires"): 410*29921a8fSScott Kruger if len(srcDict["requires"])>0: 411*29921a8fSScott Kruger return self._isRun(srcDict) 412*29921a8fSScott Kruger 413*29921a8fSScott Kruger return True 414*29921a8fSScott Kruger 415*29921a8fSScott Kruger 416*29921a8fSScott Kruger def _isRun(self,testDict): 417*29921a8fSScott Kruger """ 418*29921a8fSScott Kruger Based on the requirements listed in the src file and the petscconf.h 419*29921a8fSScott Kruger info, determine whether this test should be run or not. 420*29921a8fSScott Kruger """ 421*29921a8fSScott Kruger indent=" " 422*29921a8fSScott Kruger debug=False 423*29921a8fSScott Kruger 424*29921a8fSScott Kruger # MPI requirements 425*29921a8fSScott Kruger if testDict.has_key('nsize'): 426*29921a8fSScott Kruger if testDict['nsize']>1 and self.conf.has_key('MPI_IS_MPIUNI'): 427*29921a8fSScott Kruger if debug: print indent+"Cannot run parallel tests" 428*29921a8fSScott Kruger testDict['SKIP']="Parallel test with serial build" 429*29921a8fSScott Kruger return False 430*29921a8fSScott Kruger 431*29921a8fSScott Kruger # The requirements for the test are the sum of all the run subtests 432*29921a8fSScott Kruger if testDict.has_key('subtests'): 433*29921a8fSScott Kruger if not testDict.has_key('requires'): testDict['requires']="" 434*29921a8fSScott Kruger for stest in testDict['subtests']: 435*29921a8fSScott Kruger if testDict[stest].has_key('requires'): 436*29921a8fSScott Kruger testDict['requires']=testDict['requires']+" "+testDict[stest]['requires'] 437*29921a8fSScott Kruger 438*29921a8fSScott Kruger 439*29921a8fSScott Kruger # Now go through all requirements 440*29921a8fSScott Kruger if testDict.has_key('requires'): 441*29921a8fSScott Kruger for requirement in testDict['requires'].split(): 442*29921a8fSScott Kruger requirement=requirement.strip() 443*29921a8fSScott Kruger if not requirement: continue 444*29921a8fSScott Kruger if debug: print indent+"Requirement: ", requirement 445*29921a8fSScott Kruger isNull=False 446*29921a8fSScott Kruger if requirement.startswith("!"): 447*29921a8fSScott Kruger requirement=requirement[1:]; isNull=True 448*29921a8fSScott Kruger # Scalar requirement 449*29921a8fSScott Kruger if requirement=="complex": 450*29921a8fSScott Kruger if self.conf['PETSC_SCALAR']=='complex': 451*29921a8fSScott Kruger testDict['SKIP']="Non-complex build required" 452*29921a8fSScott Kruger if isNull: return False 453*29921a8fSScott Kruger else: 454*29921a8fSScott Kruger testDict['SKIP']="Complex build required" 455*29921a8fSScott Kruger return False 456*29921a8fSScott Kruger # Precision requirement for reals 457*29921a8fSScott Kruger if requirement in self.precision_types: 458*29921a8fSScott Kruger if self.conf['PETSC_PRECISION']==requirement: 459*29921a8fSScott Kruger testDict['SKIP']="not "+requirement+" required" 460*29921a8fSScott Kruger if isNull: return False 461*29921a8fSScott Kruger else: 462*29921a8fSScott Kruger testDict['SKIP']=requirement+" required" 463*29921a8fSScott Kruger return False 464*29921a8fSScott Kruger # Precision requirement for ints 465*29921a8fSScott Kruger if requirement in self.integer_types: 466*29921a8fSScott Kruger if requirement=="int32": 467*29921a8fSScott Kruger if self.conf['PETSC_SIZEOF_INT']==4: 468*29921a8fSScott Kruger testDict['SKIP']="not int32 required" 469*29921a8fSScott Kruger if isNull: return False 470*29921a8fSScott Kruger else: 471*29921a8fSScott Kruger testDict['SKIP']="int32 required" 472*29921a8fSScott Kruger return False 473*29921a8fSScott Kruger if requirement=="int64": 474*29921a8fSScott Kruger if self.conf['PETSC_SIZEOF_INT']==8: 475*29921a8fSScott Kruger testDict['SKIP']="NOT int64 required" 476*29921a8fSScott Kruger if isNull: return False 477*29921a8fSScott Kruger else: 478*29921a8fSScott Kruger testDict['SKIP']="int64 required" 479*29921a8fSScott Kruger return False 480*29921a8fSScott Kruger # Datafilespath 481*29921a8fSScott Kruger if requirement=="datafilespath": 482*29921a8fSScott Kruger testDict['SKIP']="Requires DATAFILESPATH" 483*29921a8fSScott Kruger return False 484*29921a8fSScott Kruger # Defines -- not sure I have comments matching 485*29921a8fSScott Kruger if "define(" in requirement: 486*29921a8fSScott Kruger reqdef=requirement.split("(")[1].split(")")[0] 487*29921a8fSScott Kruger val=(reqdef.split()[1] if " " in reqdef else "") 488*29921a8fSScott Kruger if self.conf.has_key(reqdef): 489*29921a8fSScott Kruger if val: 490*29921a8fSScott Kruger if self.conf[reqdef]==val: 491*29921a8fSScott Kruger if isNull: 492*29921a8fSScott Kruger testDict['SKIP']="Null requirement not met: "+requirement 493*29921a8fSScott Kruger return False 494*29921a8fSScott Kruger else: 495*29921a8fSScott Kruger testDict['SKIP']="Required: "+requirement 496*29921a8fSScott Kruger return False 497*29921a8fSScott Kruger else: 498*29921a8fSScott Kruger if isNull: 499*29921a8fSScott Kruger testDict['SKIP']="Null requirement not met: "+requirement 500*29921a8fSScott Kruger return False 501*29921a8fSScott Kruger else: 502*29921a8fSScott Kruger testDict['SKIP']="Requirement not met: "+requirement 503*29921a8fSScott Kruger return False 504*29921a8fSScott Kruger 505*29921a8fSScott Kruger # Rest should be packages that we can just get from conf 506*29921a8fSScott Kruger petscconfvar="PETSC_HAVE_"+requirement.upper() 507*29921a8fSScott Kruger if self.conf.get(petscconfvar): 508*29921a8fSScott Kruger if isNull: 509*29921a8fSScott Kruger testDict['SKIP']="Not "+petscconfvar+" requirement not met" 510*29921a8fSScott Kruger return False 511*29921a8fSScott Kruger else: 512*29921a8fSScott Kruger if debug: print "requirement not found: ", requirement 513*29921a8fSScott Kruger testDict['SKIP']=petscconfvar+" requirement not met" 514*29921a8fSScott Kruger return False 515*29921a8fSScott Kruger 516*29921a8fSScott Kruger return True 517*29921a8fSScott Kruger 518*29921a8fSScott Kruger def genPetscTests_summarize(self,dataDict): 519*29921a8fSScott Kruger """ 520*29921a8fSScott Kruger Required method to state what happened 521*29921a8fSScott Kruger """ 522*29921a8fSScott Kruger if not self.summarize: return 523*29921a8fSScott Kruger indent=" " 524*29921a8fSScott Kruger fhname="GenPetscTests_summarize.txt" 525*29921a8fSScott Kruger fh=open(fhname,"w") 526*29921a8fSScott Kruger print "See ", fhname 527*29921a8fSScott Kruger for root in dataDict: 528*29921a8fSScott Kruger relroot=self.relpath(self.petsc_dir,root) 529*29921a8fSScott Kruger pkg=relroot.split("/")[1] 530*29921a8fSScott Kruger fh.write(relroot+"\n") 531*29921a8fSScott Kruger allSrcs=[] 532*29921a8fSScott Kruger for lang in LANGS: allSrcs=allSrcs+self.sources[pkg][lang]['srcs'] 533*29921a8fSScott Kruger for exfile in dataDict[root]: 534*29921a8fSScott Kruger # Basic information 535*29921a8fSScott Kruger fullfile=os.path.join(root,exfile) 536*29921a8fSScott Kruger rfile=self.relpath(self.petsc_dir,fullfile) 537*29921a8fSScott Kruger builtStatus=(" Is built" if rfile in allSrcs else " Is NOT built") 538*29921a8fSScott Kruger fh.write(indent+exfile+indent*4+builtStatus+"\n") 539*29921a8fSScott Kruger 540*29921a8fSScott Kruger for test in dataDict[root][exfile]: 541*29921a8fSScott Kruger if test in self.buildkeys: continue 542*29921a8fSScott Kruger line=indent*2+test 543*29921a8fSScott Kruger fh.write(line+"\n") 544*29921a8fSScott Kruger # Looks nice to have the keys in order 545*29921a8fSScott Kruger #for key in dataDict[root][exfile][test]: 546*29921a8fSScott Kruger for key in "isrun abstracted nsize args requires script".split(): 547*29921a8fSScott Kruger if not dataDict[root][exfile][test].has_key(key): continue 548*29921a8fSScott Kruger line=indent*3+key+": "+str(dataDict[root][exfile][test][key]) 549*29921a8fSScott Kruger fh.write(line+"\n") 550*29921a8fSScott Kruger fh.write("\n") 551*29921a8fSScott Kruger fh.write("\n") 552*29921a8fSScott Kruger fh.write("\n") 553*29921a8fSScott Kruger #fh.write("\nClass Sources\n"+str(self.sources)+"\n") 554*29921a8fSScott Kruger #fh.write("\nClass Tests\n"+str(self.tests)+"\n") 555*29921a8fSScott Kruger fh.close() 556*29921a8fSScott Kruger return 557*29921a8fSScott Kruger 558*29921a8fSScott Kruger def genPetscTests(self,root,dirs,files,dataDict): 559*29921a8fSScott Kruger """ 560*29921a8fSScott Kruger Go through and parse the source files in the directory to generate 561*29921a8fSScott Kruger the examples based on the metadata contained in the source files 562*29921a8fSScott Kruger """ 563*29921a8fSScott Kruger debug=False 564*29921a8fSScott Kruger # Use examplesAnalyze to get what the makefles think are sources 565*29921a8fSScott Kruger #self.examplesAnalyze(root,dirs,files,anlzDict) 566*29921a8fSScott Kruger 567*29921a8fSScott Kruger dataDict[root]={} 568*29921a8fSScott Kruger 569*29921a8fSScott Kruger for exfile in files: 570*29921a8fSScott Kruger #TST: Until we replace files, still leaving the orginals as is 571*29921a8fSScott Kruger #if not exfile.startswith("new_"+"ex"): continue 572*29921a8fSScott Kruger if not exfile.startswith("ex"): continue 573*29921a8fSScott Kruger 574*29921a8fSScott Kruger # Convenience 575*29921a8fSScott Kruger fullex=os.path.join(root,exfile) 576*29921a8fSScott Kruger relpfile=self.relpath(self.petsc_dir,fullex) 577*29921a8fSScott Kruger if debug: print relpfile 578*29921a8fSScott Kruger dataDict[root].update(testparse.parseTestFile(fullex)) 579*29921a8fSScott Kruger # Need to check and make sure tests are in the file 580*29921a8fSScott Kruger # if verbosity>=1: print relpfile 581*29921a8fSScott Kruger if dataDict[root].has_key(exfile): 582*29921a8fSScott Kruger self.genScriptsAndInfo(exfile,root,dataDict[root][exfile]) 583*29921a8fSScott Kruger 584*29921a8fSScott Kruger return 585*29921a8fSScott Kruger 586*29921a8fSScott Kruger def walktree(self,top,action="printFiles"): 587*29921a8fSScott Kruger """ 588*29921a8fSScott Kruger Walk a directory tree, starting from 'top' 589*29921a8fSScott Kruger """ 590*29921a8fSScott Kruger #print "action", action 591*29921a8fSScott Kruger # Goal of action is to fill this dictionary 592*29921a8fSScott Kruger dataDict={} 593*29921a8fSScott Kruger for root, dirs, files in os.walk(top, topdown=False): 594*29921a8fSScott Kruger if not "examples" in root: continue 595*29921a8fSScott Kruger if not os.path.isfile(os.path.join(root,"makefile")): continue 596*29921a8fSScott Kruger bname=os.path.basename(root.rstrip("/")) 597*29921a8fSScott Kruger if bname=="tests" or bname=="tutorials": 598*29921a8fSScott Kruger eval("self."+action+"(root,dirs,files,dataDict)") 599*29921a8fSScott Kruger if type(top) != types.StringType: 600*29921a8fSScott Kruger raise TypeError("top must be a string") 601*29921a8fSScott Kruger # Now summarize this dictionary 602*29921a8fSScott Kruger eval("self."+action+"_summarize(dataDict)") 603*29921a8fSScott Kruger return dataDict 604*29921a8fSScott Kruger 605*29921a8fSScott Kruger def gen_gnumake(self, fd,prefix='srcs-'): 606*29921a8fSScott Kruger """ 607*29921a8fSScott Kruger Overwrite of the method in the base PETSc class 608*29921a8fSScott Kruger """ 609*29921a8fSScott Kruger def write(stem, srcs): 610*29921a8fSScott Kruger fd.write('%s :=\n' % stem) 611*29921a8fSScott Kruger for lang in LANGS: 612*29921a8fSScott Kruger fd.write('%(stem)s.%(lang)s := %(srcs)s\n' % dict(stem=stem, lang=lang, srcs=' '.join(srcs[lang]['srcs']))) 613*29921a8fSScott Kruger fd.write('%(stem)s += $(%(stem)s.%(lang)s)\n' % dict(stem=stem, lang=lang)) 614*29921a8fSScott Kruger for pkg in PKGS: 615*29921a8fSScott Kruger srcs = self.gen_pkg(pkg) 616*29921a8fSScott Kruger write(prefix + pkg, srcs) 617*29921a8fSScott Kruger return self.gendeps 618*29921a8fSScott Kruger 619*29921a8fSScott Kruger def gen_pkg(self, pkg): 620*29921a8fSScott Kruger """ 621*29921a8fSScott Kruger Overwrite of the method in the base PETSc class 622*29921a8fSScott Kruger """ 623*29921a8fSScott Kruger return self.sources[pkg] 624*29921a8fSScott Kruger 625*29921a8fSScott Kruger def write_gnumake(self,dataDict): 626*29921a8fSScott Kruger """ 627*29921a8fSScott Kruger Write out something similar to files from gmakegen.py 628*29921a8fSScott Kruger 629*29921a8fSScott Kruger There is not a lot of has_key type checking because 630*29921a8fSScott Kruger should just work and need to know if there are bugs 631*29921a8fSScott Kruger 632*29921a8fSScott Kruger Test depends on script which also depends on source 633*29921a8fSScott Kruger file, but since I don't have a good way generating 634*29921a8fSScott Kruger acting on a single file (oops) just depend on 635*29921a8fSScott Kruger executable which in turn will depend on src file 636*29921a8fSScott Kruger """ 637*29921a8fSScott Kruger # Open file 638*29921a8fSScott Kruger arch_files = self.arch_path('lib','petsc','conf', 'testfiles') 639*29921a8fSScott Kruger arg_files = self.arch_path('lib','petsc','conf', 'testargfiles') 640*29921a8fSScott Kruger fd = open(arch_files, 'w') 641*29921a8fSScott Kruger fa = open(arg_files, 'w') 642*29921a8fSScott Kruger 643*29921a8fSScott Kruger # Write out the sources 644*29921a8fSScott Kruger gendeps = self.gen_gnumake(fd,prefix="testsrcs-") 645*29921a8fSScott Kruger 646*29921a8fSScott Kruger # Write out the tests and execname targets 647*29921a8fSScott Kruger fd.write("\n#Tests and executables\n") # Delimiter 648*29921a8fSScott Kruger testdeps=" ".join(["test-"+pkg for pkg in PKGS]) 649*29921a8fSScott Kruger testexdeps=" ".join(["test-ex-"+pkg for pkg in PKGS]) 650*29921a8fSScott Kruger fd.write("test: testex "+testdeps+" report_tests\n") # Main test target 651*29921a8fSScott Kruger # Add executables to build right way to make the `make test` look 652*29921a8fSScott Kruger # nicer 653*29921a8fSScott Kruger fd.write("testex: "+testexdeps+"\n") # Main test target 654*29921a8fSScott Kruger 655*29921a8fSScott Kruger for pkg in PKGS: 656*29921a8fSScott Kruger # These grab the ones that are built 657*29921a8fSScott Kruger # Package tests 658*29921a8fSScott Kruger testdeps=" ".join(["test-"+pkg+"-"+lang for lang in LANGS]) 659*29921a8fSScott Kruger fd.write("test-"+pkg+": "+testdeps+"\n") 660*29921a8fSScott Kruger testexdeps=" ".join(["test-ex-"+pkg+"-"+lang for lang in LANGS]) 661*29921a8fSScott Kruger fd.write("test-ex-"+pkg+": "+testexdeps+"\n") 662*29921a8fSScott Kruger # This needs work 663*29921a8fSScott Kruger if self.single_ex: 664*29921a8fSScott Kruger execname=pkg+"-ex" 665*29921a8fSScott Kruger fd.write(execname+": "+" ".join(self.objects[pkg])+"\n\n") 666*29921a8fSScott Kruger for lang in LANGS: 667*29921a8fSScott Kruger testdeps="" 668*29921a8fSScott Kruger for ftest in self.tests[pkg][lang]: 669*29921a8fSScott Kruger test=os.path.basename(ftest) 670*29921a8fSScott Kruger basedir=os.path.dirname(ftest) 671*29921a8fSScott Kruger testdeps=testdeps+" "+self.nameSpace(test,basedir) 672*29921a8fSScott Kruger fd.write("test-"+pkg+"-"+lang+":"+testdeps+"\n") 673*29921a8fSScott Kruger 674*29921a8fSScott Kruger # test targets 675*29921a8fSScott Kruger for ftest in self.tests[pkg][lang]: 676*29921a8fSScott Kruger test=os.path.basename(ftest) 677*29921a8fSScott Kruger basedir=os.path.dirname(ftest) 678*29921a8fSScott Kruger testdir="${TESTDIR}/"+basedir+"/" 679*29921a8fSScott Kruger nmtest=self.nameSpace(test,basedir) 680*29921a8fSScott Kruger rundir=os.path.join(testdir,test) 681*29921a8fSScott Kruger #print test, nmtest 682*29921a8fSScott Kruger script=test+".sh" 683*29921a8fSScott Kruger 684*29921a8fSScott Kruger # Deps 685*29921a8fSScott Kruger exfile=self.tests[pkg][lang][ftest]['exfile'] 686*29921a8fSScott Kruger fullex=os.path.join(self.petsc_dir,exfile) 687*29921a8fSScott Kruger localexec=self.tests[pkg][lang][ftest]['exec'] 688*29921a8fSScott Kruger execname=os.path.join(testdir,localexec) 689*29921a8fSScott Kruger 690*29921a8fSScott Kruger # SKIP and TODO tests do not depend on exec 691*29921a8fSScott Kruger if exfile in self.sources[pkg][lang]['srcs']: 692*29921a8fSScott Kruger #print "Found dep: "+exfile, execname 693*29921a8fSScott Kruger fd.write(nmtest+": "+execname+"\n") 694*29921a8fSScott Kruger else: 695*29921a8fSScott Kruger # Still add dependency to file 696*29921a8fSScott Kruger fd.write(nmtest+": "+fullex+"\n") 697*29921a8fSScott Kruger cmd=testdir+"/"+script 698*29921a8fSScott Kruger fd.write("\t-@"+cmd+"\n") 699*29921a8fSScott Kruger # Now write the args: 700*29921a8fSScott Kruger fa.write(nmtest+"_ARGS='"+self.tests[pkg][lang][ftest]['argLabel']+"'\n") 701*29921a8fSScott Kruger 702*29921a8fSScott Kruger # executable targets -- add these to build earlier 703*29921a8fSScott Kruger testexdeps="" 704*29921a8fSScott Kruger if not self.single_ex: 705*29921a8fSScott Kruger for exfile in self.sources[pkg][lang]['srcs']: 706*29921a8fSScott Kruger localexec=os.path.basename(os.path.splitext(exfile)[0]) 707*29921a8fSScott Kruger basedir=os.path.dirname(exfile) 708*29921a8fSScott Kruger testdir="${TESTDIR}/"+basedir+"/" 709*29921a8fSScott Kruger execname=os.path.join(testdir,localexec) 710*29921a8fSScott Kruger testexdeps=testexdeps+" "+execname 711*29921a8fSScott Kruger fd.write("test-ex-"+pkg+"-"+lang+":"+testexdeps+"\n") 712*29921a8fSScott Kruger 713*29921a8fSScott Kruger for exfile in self.sources[pkg][lang]['srcs']: 714*29921a8fSScott Kruger root=os.path.join(self.petsc_dir,os.path.dirname(exfile)) 715*29921a8fSScott Kruger basedir=os.path.dirname(exfile) 716*29921a8fSScott Kruger testdir="${TESTDIR}/"+basedir+"/" 717*29921a8fSScott Kruger base=os.path.basename(exfile) 718*29921a8fSScott Kruger objfile=testdir+os.path.splitext(base)[0]+".o" 719*29921a8fSScott Kruger linker=self.getLanguage(exfile)[0].upper()+"LINKER" 720*29921a8fSScott Kruger if self.sources[pkg][lang].has_key(exfile): 721*29921a8fSScott Kruger # Dependency for file 722*29921a8fSScott Kruger objfile=objfile+" "+self.sources[pkg][lang][exfile] 723*29921a8fSScott Kruger print objfile 724*29921a8fSScott Kruger if not self.single_ex: 725*29921a8fSScott Kruger localexec=os.path.basename(os.path.splitext(exfile)[0]) 726*29921a8fSScott Kruger execname=os.path.join(testdir,localexec) 727*29921a8fSScott Kruger localobj=os.path.basename(objfile) 728*29921a8fSScott Kruger petsc_lib="${PETSC_"+pkg.upper()+"_LIB}" 729*29921a8fSScott Kruger fd.write("\n"+execname+": "+objfile+" ${libpetscall}\n") 730*29921a8fSScott Kruger # There should be a better way here 731*29921a8fSScott Kruger line="\t-cd "+testdir+"; ${"+linker+"} -o "+localexec+" "+localobj+" "+petsc_lib 732*29921a8fSScott Kruger fd.write(line+"\n") 733*29921a8fSScott Kruger linker=self.getLanguage(exfile)[0].upper()+"LINKER" 734*29921a8fSScott Kruger 735*29921a8fSScott Kruger fd.write("helptests:\n\t -@grep '^[a-z]' ${generatedtest} | cut -f1 -d:\n") 736*29921a8fSScott Kruger # Write out tests 737*29921a8fSScott Kruger return 738*29921a8fSScott Kruger 739*29921a8fSScott Kruger def writeHarness(self,output,dataDict): 740*29921a8fSScott Kruger """ 741*29921a8fSScott Kruger This is set up to write out multiple harness even if only gnumake 742*29921a8fSScott Kruger is supported now 743*29921a8fSScott Kruger """ 744*29921a8fSScott Kruger eval("self.write_"+output+"(dataDict)") 745*29921a8fSScott Kruger return 746*29921a8fSScott Kruger 747*29921a8fSScott Krugerdef main(petsc_dir=None, petsc_arch=None, output=None, verbose=False, single_ex=False): 748*29921a8fSScott Kruger if output is None: 749*29921a8fSScott Kruger output = 'gnumake' 750*29921a8fSScott Kruger 751*29921a8fSScott Kruger 752*29921a8fSScott Kruger pEx=generateExamples(petsc_dir=petsc_dir, petsc_arch=petsc_arch, verbose=verbose, single_ex=single_ex) 753*29921a8fSScott Kruger dataDict=pEx.walktree(os.path.join(pEx.petsc_dir,'src'),action="genPetscTests") 754*29921a8fSScott Kruger pEx.writeHarness(output,dataDict) 755*29921a8fSScott Kruger 756*29921a8fSScott Krugerif __name__ == '__main__': 757*29921a8fSScott Kruger import optparse 758*29921a8fSScott Kruger parser = optparse.OptionParser() 759*29921a8fSScott Kruger parser.add_option('--verbose', help='Show mismatches between makefiles and the filesystem', action='store_true', default=False) 760*29921a8fSScott Kruger parser.add_option('--petsc-arch', help='Set PETSC_ARCH different from environment', default=os.environ.get('PETSC_ARCH')) 761*29921a8fSScott Kruger parser.add_option('--output', help='Location to write output file', default=None) 762*29921a8fSScott Kruger parser.add_option('-s', '--single_executable', dest='single_executable', action="store_false", help='Whether there should be single executable per src subdir. Default is false') 763*29921a8fSScott Kruger opts, extra_args = parser.parse_args() 764*29921a8fSScott Kruger if extra_args: 765*29921a8fSScott Kruger import sys 766*29921a8fSScott Kruger sys.stderr.write('Unknown arguments: %s\n' % ' '.join(extra_args)) 767*29921a8fSScott Kruger exit(1) 768*29921a8fSScott Kruger main(petsc_arch=opts.petsc_arch, output=opts.output, verbose=opts.verbose, single_ex=opts.single_executable) 769