doc:user:tutorials:test_python
Differences
This shows you the differences between two versions of the page.
doc:user:tutorials:test_python [2020/09/08 16:06] – created boman | doc:user:tutorials:test_python [2020/09/08 16:26] (current) – removed boman | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | <code python> | ||
- | # | ||
- | # -*- coding: utf-8 -*- | ||
- | # | ||
- | # lance une serie de tests dans des repertoires donnes | ||
- | from __future__ import print_function | ||
- | from __future__ import absolute_import | ||
- | from __future__ import division | ||
- | from future import standard_library | ||
- | standard_library.install_aliases() | ||
- | from builtins import zip | ||
- | from builtins import range | ||
- | from builtins import object | ||
- | from past.utils import old_div | ||
- | import fnmatch, sys, os, os.path, shutil, glob, platform, datetime | ||
- | import re, socket | ||
- | import threading, queue, time | ||
- | import traceback, subprocess | ||
- | from operator import itemgetter | ||
- | from .pyutils import * | ||
- | import toolbox.stp2py | ||
- | |||
- | from .concolor import * | ||
- | thcolors = [ fg_green, fg_cyan, fg_yellow, fg_magenta, fg_blue, fg_red ] | ||
- | |||
- | writelock = threading.Lock() | ||
- | fslock = threading.Lock() | ||
- | popenlock = threading.Lock() | ||
- | |||
- | class BatTest(object): | ||
- | def __init__(self, | ||
- | self.battery = battery | ||
- | self.fullfile = fullfile | ||
- | self.num = num | ||
- | self.badstatus=False | ||
- | # | ||
- | def write(self, string): | ||
- | writelock.acquire() | ||
- | setColor(thcolors[self.num%len(thcolors)]) | ||
- | sys.stdout.write( "[%d] %s" % (self.num, string) ) | ||
- | resetColor() | ||
- | writelock.release() | ||
- | # -- LANCE METAFOR -- | ||
- | def runModule(self): | ||
- | cleanneeded=False | ||
- | files=glob.glob(self.fullfile) | ||
- | files.sort() | ||
- | for pyfile in files: # utile si serie | ||
- | module = fileToModule(pyfile, | ||
- | # | ||
- | resfile = module.replace(' | ||
- | resdir = os.path.dirname(resfile) | ||
- | if resdir == '' | ||
- | resdir = os.path.dirname(os.path.abspath(resfile)) # abspath necessaire si le test est dans " | ||
- | startT = datetime.datetime.now() | ||
- | # determine method | ||
- | method=' | ||
- | for mods in self.battery.cplx_exec: | ||
- | if " | ||
- | mods = mods + " | ||
- | if fnmatch.fnmatch(module, | ||
- | method=' | ||
- | break | ||
- | for mods in self.battery.cplx_import: | ||
- | if " | ||
- | mods = mods + " | ||
- | if fnmatch.fnmatch(module, | ||
- | method=' | ||
- | break | ||
- | for mods in self.battery.restart: | ||
- | if " | ||
- | mods = mods + " | ||
- | if fnmatch.fnmatch(module, | ||
- | method=' | ||
- | break | ||
- | # restart : on renomme le .res en .res1 | ||
- | if method == ' | ||
- | resfile = module.replace(' | ||
- | #print " | ||
- | | ||
- | # test metafor | ||
- | if not os.path.isfile(resfile) \ | ||
- | or os.path.getmtime(resfile) < os.path.getmtime(pyfile): | ||
- | cleanneeded=True | ||
- | try: | ||
- | | ||
- | cwd=os.getcwd() | ||
- | # resDir | ||
- | fslock.acquire() | ||
- | if not os.path.isdir(resdir): | ||
- | os.makedirs(resdir) | ||
- | fslock.release() | ||
- | # resfile | ||
- | fileout = open(resfile,' | ||
- | |||
- | # | ||
- | #if self.battery.nice: | ||
- | # cmd = [self.battery.nice]+cmd | ||
- | cmd = self.battery.startCmd + self.battery.nice + self.battery.affinity + [self.battery.python] | ||
- | # print ("cmd = ", cmd) | ||
- | # python 3 " | ||
- | # this prevents us from seeing python print and std::cout is the correct order | ||
- | # => we set PYTHONUNBUFFERED to true (we could use ' | ||
- | os.environ[' | ||
- | # subprocess | ||
- | global popenlock | ||
- | popenlock.acquire() | ||
- | if isUnix(): # sans close_fds, ca freeze | ||
- | p = subprocess.Popen(cmd, | ||
- | else: # si nice+Windows => " | ||
- | subProcessFlag = self.battery.getSubprocessFlags() | ||
- | p = subprocess.Popen(cmd, | ||
- | popenlock.release() | ||
- | # commandes communes : | ||
- | pin = p.stdin | ||
- | pin.write(b" | ||
- | pin.write(b" | ||
- | if method==' | ||
- | pin.write( (" | ||
- | pin.write(b" | ||
- | | ||
- | pin.write(b" | ||
- | if self.battery.useFPE : | ||
- | pin.write(b" | ||
- | pin.write(b" | ||
- | # definition du nombre de threads | ||
- | pin.write(b" | ||
- | pin.write( (" | ||
- | # pin.write(b" | ||
- | |||
- | # Execution .pythonrc.py | ||
- | pin.write( (" | ||
- | # | ||
- | pin.write( (" | ||
- | |||
- | # WDirRoot (pour sauvegarde sur disques locaux sur le cluster) | ||
- | if self.battery.wDRoot != '' | ||
- | self.write(" | ||
- | pin.write( (" | ||
- | | ||
- | # selon type de run | ||
- | if method==' | ||
- | self.write(" | ||
- | # note: past.builtins.execfile does not always work | ||
- | # (apps.remeshing2.fullAuto.taylor2dImpRemeshing fails? | ||
- | pin.write( (" | ||
- | elif method==' | ||
- | self.write(" | ||
- | pin.write( (" | ||
- | elif method==' | ||
- | self.write(" | ||
- | pin.write( (" | ||
- | pin.write( (" | ||
- | else: | ||
- | self.write(" | ||
- | pin.write( (" | ||
- | pin.write(b" | ||
- | self.write(" | ||
- | pin.close() | ||
- | retcode = p.wait() | ||
- | |||
- | fileout.close() | ||
- | # 0 < retcode < 127 => USER | ||
- | # 128 < retcode < 255 => Unix Signals | ||
- | # 139 => Unix seg-fault (sigsegv = 11 = 139-128) | ||
- | # retcode = -1073741510 : sig-break windows | ||
- | if not isUnix() and retcode< | ||
- | self.cleanModule() | ||
- | raise Exception(" | ||
- | #print " | ||
- | # | ||
- | |||
- | except (Exception, KeyboardInterrupt) as e: # catch SigBreaks, bad retcodes, etc | ||
- | self.write(" | ||
- | try : # si l' | ||
- | fileout.close() | ||
- | except : | ||
- | pass | ||
- | self.cleanModule() | ||
- | raise | ||
- | |||
- | stopT = datetime.datetime.now() | ||
- | self.write(" | ||
- | |||
- | self.postInfos(pyfile, | ||
- | if self.badstatus: | ||
- | return | ||
- | |||
- | if cleanneeded and not self.battery.keepFacs: | ||
- | self.postCleanModule() | ||
- | |||
- | def postInfos(self, | ||
- | if os.path.isfile(resfile): | ||
- | tscfound=False | ||
- | for line in open(resfile,' | ||
- | if not tscfound and line.find(" | ||
- | tscfound=True | ||
- | if line.find(" | ||
- | #print "line = ", line | ||
- | self.dispWarningAndTouch(pyfile, | ||
- | if line.find(" | ||
- | self.dispWarningAndTouch(pyfile, | ||
- | if line.find(" | ||
- | self.dispWarningAndTouch(pyfile, | ||
- | if not tscfound: | ||
- | self.dispWarningAndTouch(pyfile, | ||
- | else: | ||
- | self.dispWarningAndTouch(pyfile, | ||
- | |||
- | def dispWarningAndTouch(self, | ||
- | self.badstatus=True | ||
- | self.write(" | ||
- | # touch pyfile | ||
- | if os.path.isfile(pyfile): | ||
- | # | ||
- | os.utime(pyfile, | ||
- | |||
- | def cleanModule(self): | ||
- | self.postCleanModule() # au cas ou... | ||
- | for pyfile in glob.glob(self.fullfile): | ||
- | # .pyc | ||
- | for ext in [' | ||
- | pycfile = pyfile.replace(' | ||
- | if os.path.isfile(pycfile): | ||
- | try: # sur les versions installees, les pyc appartiennent a l'os. les utilisateurs ne peuvent pas toujours y toucher... | ||
- | os.remove(pycfile) | ||
- | self.write(" | ||
- | except: | ||
- | self.write(" | ||
- | # .res | ||
- | module = fileToModule(pyfile, | ||
- | resfile = module.replace(' | ||
- | if os.path.isfile(resfile): | ||
- | os.remove(resfile) | ||
- | self.write(" | ||
- | # .tsc | ||
- | tscfile = module.replace(' | ||
- | if os.path.isfile(tscfile): | ||
- | os.remove(tscfile) | ||
- | self.write(" | ||
- | # res dir | ||
- | resdir = os.path.dirname(os.path.abspath(resfile)) # abspath necessaire si le test est dans " | ||
- | fslock.acquire() | ||
- | self.cleanDir(resdir) | ||
- | fslock.release() | ||
- | |||
- | def cleanDir(self, | ||
- | ld=glob.glob(dir) | ||
- | for fil in ld: | ||
- | if os.path.isdir(fil): | ||
- | try: | ||
- | # | ||
- | os.rmdir(dir) # only works if empty | ||
- | self.write(" | ||
- | except: | ||
- | pass | ||
- | |||
- | def postCleanModule(self): | ||
- | try: | ||
- | #print " | ||
- | if self.battery.wDRoot != '' | ||
- | workspaceBase = os.path.join(self.battery.wDRoot, | ||
- | else: | ||
- | workspaceBase =' | ||
- | for file in glob.glob(self.fullfile): | ||
- | # facs | ||
- | module = fileToModule(file, | ||
- | workspace = os.path.join(workspaceBase, | ||
- | if os.path.isdir(workspace): | ||
- | shutil.rmtree(workspace) | ||
- | self.write(" | ||
- | # parametric | ||
- | workspace = os.path.join(workspaceBase, | ||
- | if os.path.isdir(workspace): | ||
- | shutil.rmtree(workspace) | ||
- | self.write(" | ||
- | # teste si c'est une serie (tests par enchainement) | ||
- | reg1=r" | ||
- | exp1= re.compile(reg1) | ||
- | m = exp1.match(module) | ||
- | if m: | ||
- | module = m.group(1) | ||
- | workspace = os.path.join(workspaceBase, | ||
- | if os.path.isdir(workspace): | ||
- | shutil.rmtree(workspace) | ||
- | self.write(" | ||
- | # crasses annexes | ||
- | # ... | ||
- | except: # WindowsError si fichiers en cours d' | ||
- | pass | ||
- | |||
- | def verifModule(self): | ||
- | tsc=[] | ||
- | leaks=[] | ||
- | files=glob.glob(self.fullfile) | ||
- | files.sort() | ||
- | for pyfile in files: | ||
- | module = fileToModule(pyfile, | ||
- | resfile = module.replace(' | ||
- | if os.path.isfile(resfile): | ||
- | for line in open(resfile,' | ||
- | if line.find(" | ||
- | leaks.append(line) | ||
- | elif line.find(" | ||
- | tsc.append(line) | ||
- | if(len(tsc)): | ||
- | return tsc + leaks # on retourne les leaks uniquement si le test retourne qq cghose d' | ||
- | else: | ||
- | return tsc | ||
- | |||
- | def buildTSCFile(self): | ||
- | files = glob.glob(self.fullfile) | ||
- | files.sort() | ||
- | for pyfile in files: | ||
- | tscs = [] | ||
- | leaks = [] | ||
- | module = fileToModule(pyfile, | ||
- | resfile = module.replace(' | ||
- | if os.path.isfile(resfile): | ||
- | for line in open(resfile,' | ||
- | if line.find(" | ||
- | leaks.append(line) | ||
- | elif line.find(" | ||
- | tscs.append(line) | ||
- | fname = module.replace(' | ||
- | tscFile = open(fname, ' | ||
- | if len(tscs) == 0: | ||
- | tscFile.write(" | ||
- | else: | ||
- | for tsc in tscs: | ||
- | tscFile.write(" | ||
- | for leak in leaks: | ||
- | tscFile.write(" | ||
- | tscFile.close() | ||
- | |||
- | |||
- | def diffTSC(self): | ||
- | import re, difflib | ||
- | # diff de valeur : | ||
- | # regTsc : | ||
- | # groupe 1 : code du TSC | ||
- | # groupe 2 : nom de la valeur | ||
- | # groupe 3 : valeur | ||
- | self.regTsc | ||
- | self.regTscTol | ||
- | self.regFailed | ||
- | vals={} | ||
- | files = glob.glob(self.fullfile) | ||
- | files.sort() | ||
- | for pyfile in files: | ||
- | tscs = {} | ||
- | module = fileToModule(pyfile, | ||
- | srcFile = pyfile.replace(' | ||
- | self.fillEntries(srcFile, | ||
- | tscFile = os.path.abspath(module.replace(' | ||
- | self.fillEntries(tscFile, | ||
- | resFile = os.path.abspath(module.replace(' | ||
- | #Check Values | ||
- | for code, txt in list(tscs.items()): | ||
- | if code not in vals: | ||
- | vals[code]=[] | ||
- | for name, diff in list(txt.items()) : | ||
- | if diff.old == diff.new: | ||
- | continue | ||
- | elif diff.old != Diff.MISSING and diff.new != Diff.MISSING: | ||
- | try: | ||
- | old = float(diff.old) | ||
- | new = float(diff.new) | ||
- | if new < (old-diff.tol) or (old+diff.tol) < new : | ||
- | color = "# | ||
- | ad = new-old | ||
- | if ad.is_integer(): | ||
- | absDiff = ' | ||
- | else: | ||
- | absDiff = ' | ||
- | try: | ||
- | vd = old_div((new-old), | ||
- | vDiff = ' | ||
- | except: | ||
- | vDiff = ' | ||
- | vals[code].append([color, | ||
- | except: | ||
- | absDiff = ' | ||
- | vDiff = ' | ||
- | vals[code].append([color, | ||
- | |||
- | elif diff.old==Diff.MISSING and diff.new != Diff.MISSING: | ||
- | color="# | ||
- | absDiff = diff.new | ||
- | vDiff = ' | ||
- | vals[code].append([color, | ||
- | elif diff.old!=Diff.MISSING and diff.new==Diff.MISSING: | ||
- | color="# | ||
- | absDiff = diff.old | ||
- | vDiff = ' | ||
- | vals[code].append([color, | ||
- | return vals | ||
- | |||
- | def fillEntries(self, | ||
- | if os.path.isfile(file): | ||
- | for line in open(file,' | ||
- | n = self.regTsc.match(line) | ||
- | if src : | ||
- | m = self.regTscTol.match(line) | ||
- | else : | ||
- | m = None | ||
- | o = self.regFailed.match(line) | ||
- | if m : | ||
- | code = m.group(1) | ||
- | txt = module + " - " + m.group(2) | ||
- | val = m.group(3) | ||
- | if code not in diffs: | ||
- | diffs[code]={} | ||
- | if txt not in diffs[code]: | ||
- | diffs[code][txt]=Diff() | ||
- | diffs[code][txt].old=val | ||
- | diffs[code][txt].tol=float(m.group(4)) | ||
- | elif n: | ||
- | code = n.group(1) | ||
- | txt = module + " - " + n.group(2) | ||
- | val = n.group(3) | ||
- | if code not in diffs: | ||
- | diffs[code]={} | ||
- | if txt not in diffs[code]: | ||
- | diffs[code][txt]=Diff() | ||
- | if src: | ||
- | diffs[code][txt].old=val | ||
- | else: | ||
- | diffs[code][txt].new=val | ||
- | elif o : | ||
- | code = ' | ||
- | if code not in diffs: | ||
- | diffs[code]={} | ||
- | if module not in diffs[code]: | ||
- | diffs[code][module]=Diff() | ||
- | |||
- | if src: | ||
- | diffs[code][module].old=' | ||
- | else: | ||
- | diffs[code][module].new=' | ||
- | else : | ||
- | print(" | ||
- | print(" | ||
- | else: | ||
- | code = ' | ||
- | if code not in diffs: | ||
- | diffs[code]={} | ||
- | if module not in diffs[code]: | ||
- | diffs[code][module]=Diff() | ||
- | if src: | ||
- | diffs[code][module].old=' | ||
- | else: | ||
- | diffs[code][module].new=' | ||
- | # ---------------------------------------------------------------------------------------- | ||
- | # -- diffs -- | ||
- | |||
- | head=r""" | ||
- | < | ||
- | <html xmlns=" | ||
- | < | ||
- | <meta http-equiv=" | ||
- | < | ||
- | <style type=" | ||
- | <!-- | ||
- | body { | ||
- | font-family: | ||
- | font-size: 12px; | ||
- | } | ||
- | p { | ||
- | font-family: | ||
- | font-size: 12px; | ||
- | } | ||
- | table { | ||
- | font-size: 12px; | ||
- | } | ||
- | h2 { | ||
- | font-size: 18px; | ||
- | } | ||
- | th { | ||
- | color: #FFFFFF; | ||
- | background-color: | ||
- | } | ||
- | .style1 {font-family: | ||
- | --> | ||
- | </ | ||
- | |||
- | <script src=" | ||
- | <script src=" | ||
- | <link rel=" | ||
- | <script type=" | ||
- | |||
- | <script langage=" | ||
- | |||
- | function initDataTable(tableID) { | ||
- | $("#" | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | { " | ||
- | { " | ||
- | { " | ||
- | { " | ||
- | { " | ||
- | }); | ||
- | $("#" | ||
- | } | ||
- | |||
- | function initDataTableWithTotal(tableID) { | ||
- | $("#" | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | { " | ||
- | { " | ||
- | { " | ||
- | { " | ||
- | { " | ||
- | footerCallback: | ||
- | var api = this.api(); | ||
- | // Remove the formatting to get float data for summation | ||
- | var floatVal = function ( i ) { | ||
- | if(typeof(i) == " | ||
- | var temp = Number(i.replace(/ | ||
- | if(Number.isNaN(temp)) | ||
- | return 0; | ||
- | else | ||
- | return temp;} | ||
- | else{ | ||
- | return Number(i);} | ||
- | }; | ||
- | |||
- | for (var i = 1; i < 5; ++i) | ||
- | { | ||
- | // Total over all pages | ||
- | var total = api.column(i).data().reduce( function (a, b) { | ||
- | return floatVal(a) + floatVal(b); | ||
- | }, 0 ); | ||
- | |||
- | // Total over this page | ||
- | var pageTotal = api.column( i, { page: ' | ||
- | return floatVal(a) + floatVal(b); | ||
- | }, 0 ); | ||
- | |||
- | var percent = pageTotal/ | ||
- | // Update footer | ||
- | $( api.column( i ).footer() ).html( | ||
- | "" | ||
- | ); | ||
- | } | ||
- | } | ||
- | }); | ||
- | $("#" | ||
- | } | ||
- | |||
- | function diffTSC(color, | ||
- | var msg1 = '< | ||
- | msg1 += '< | ||
- | if (!(pyFile == '' | ||
- | if (!(resFile == '' | ||
- | msg1 +='</ | ||
- | var msg2 = '< | ||
- | var msg3 = '< | ||
- | var msg4 = '< | ||
- | var msg5 = '< | ||
- | document.writeln(msg1+msg2+msg3+msg4+msg5) | ||
- | } | ||
- | function diffTSC2(color, | ||
- | var msg1 = '< | ||
- | msg1 += '< | ||
- | if (!(pyFile == '' | ||
- | if (!(resFile == '' | ||
- | if (!(oldTscFile == '' | ||
- | if (!(newTscFile == '' | ||
- | msg1 +='</ | ||
- | var msg2 = '< | ||
- | var msg3 = '< | ||
- | var msg4 = '< | ||
- | var msg5 = '< | ||
- | document.writeln(msg1+msg2+msg3+msg4+msg5) | ||
- | } | ||
- | |||
- | function headTxt(ref, | ||
- | var msg1 = '<a name=' | ||
- | msg1 += '< | ||
- | var msg2 = '<a href="# | ||
- | var msg3 = '< | ||
- | document.writeln(msg1+msg2+msg3) | ||
- | } | ||
- | |||
- | function headTxtWithTotal(ref, | ||
- | var msg1 = '<a name=' | ||
- | msg1 += '< | ||
- | var msg2 = '<a href="# | ||
- | var msg3 = '< | ||
- | var msg4 = '< | ||
- | document.writeln(msg1+msg2+msg3+msg4) | ||
- | } | ||
- | |||
- | function switchMode() { | ||
- | """ | ||
- | |||
- | class Diff(object): | ||
- | """ | ||
- | One diff (old & new numeric values) | ||
- | """ | ||
- | MISSING=" | ||
- | def __init__(self): | ||
- | self.new = self.MISSING | ||
- | self.old = self.MISSING | ||
- | self.tol = 0.0 | ||
- | |||
- | class DiffGenerator(object): | ||
- | def __init__(self, | ||
- | self.battery | ||
- | self.diffpart = part | ||
- | if codes : | ||
- | self.codes | ||
- | else : | ||
- | self.codes | ||
- | |||
- | def htmlhead(self): | ||
- | global head | ||
- | return head % (machineid(), | ||
- | |||
- | def diffOneCode(self, | ||
- | """ | ||
- | diff one given result file - returns html code | ||
- | """ | ||
- | import sys, re | ||
- | |||
- | diffs={} | ||
- | # match a " | ||
- | regu=r" | ||
- | # group(1) : + ou - | ||
- | # group(2) : nom du module | ||
- | # group(3) : [TSC-*] | ||
- | # group(4) : nom de la courbe OU exp_* (parametric) | ||
- | # group(5) : nom de la variable (parametric) | ||
- | # group(6) : valeur | ||
- | exp1 = re.compile( regu ) | ||
- | # match failed test | ||
- | regu=r" | ||
- | # group(1) : + ou - | ||
- | # group(2) : nom du module | ||
- | # group(3) : FAILED! | ||
- | exp2 = re.compile( regu ) | ||
- | |||
- | #for l in lines: | ||
- | # l=l[:-1] # remove newline (pour difflib) | ||
- | |||
- | #for l in lines.split(' | ||
- | for l in lines.splitlines(): | ||
- | m = exp1.match(l) | ||
- | n = exp2.match(l) | ||
- | if m: # a diff | ||
- | bkey = m.group(2)+" | ||
- | if m.group(5): | ||
- | bkey=bkey+" | ||
- | key=bkey | ||
- | no=1 | ||
- | while True: | ||
- | #print " | ||
- | if key not in diffs: | ||
- | diffs[ key ] = Diff() | ||
- | d = diffs[ key ] | ||
- | if m.group(1)==' | ||
- | d.new = m.group(6) | ||
- | break | ||
- | if m.group(1)==' | ||
- | d.old = m.group(6) | ||
- | break | ||
- | no+=1 | ||
- | key = '%s (%d)' % (bkey, no) # manage multiple output for the same test | ||
- | elif n: # a failed test | ||
- | key=n.group(2) | ||
- | if key not in diffs: | ||
- | diffs[ key ] = Diff() | ||
- | d = diffs[ key ] | ||
- | if n.group(1)==' | ||
- | d.new = " | ||
- | else: | ||
- | d.old = " | ||
- | |||
- | if self.diffpart: | ||
- | # on va virer tous les tests non specifies en ligne de commande | ||
- | # !! utile si on lance un repertoire particulier | ||
- | # !! ennuyeux si des tests ont ete renommes ou deplaces | ||
- | tests=set() | ||
- | for mods in self.battery.loopOn(self.battery.dirs): | ||
- | for mod in glob.glob(mods): | ||
- | tests.add(fileToModule(mod, | ||
- | sk = [x for x in list(diffs.keys()) if x.split()[0] in tests] # on garde que les tests lances | ||
- | #sk = diffs.keys() | ||
- | sk.sort() # sorted module names | ||
- | |||
- | vk = [diffs[k] for k in sk] # sorted diffs | ||
- | else: | ||
- | # on garde toutes les diffs independamment de ce qu'on a lance | ||
- | sk = list(diffs.keys()) | ||
- | sk.sort() | ||
- | vk = [diffs[k] for k in sk] | ||
- | |||
- | title = os.path.basename(fname) | ||
- | |||
- | tex = '< | ||
- | tex += '< | ||
- | if(code == " | ||
- | tex += ' | ||
- | else: | ||
- | tex += ' | ||
- | |||
- | for k, v in zip(sk, vk): | ||
- | color="# | ||
- | if v.old==v.new: | ||
- | color="# | ||
- | elif (v.old==Diff.MISSING or v.new==Diff.MISSING): | ||
- | color="# | ||
- | vdiff = None | ||
- | absDiff = None | ||
- | trueDiff = True | ||
- | try: | ||
- | vnew=float(v.new) | ||
- | vold=float(v.old) | ||
- | vdiff=(float(v.new)-float(v.old))/ | ||
- | absDiff = (float(v.new)-float(v.old)) | ||
- | #if (abs(vdiff)< | ||
- | # trueDiff = False | ||
- | vdiff = ' | ||
- | |||
- | if absDiff.is_integer() : | ||
- | absDiff = ' | ||
- | else: | ||
- | absDiff = ' | ||
- | except: | ||
- | vdiff = ' | ||
- | absDiff = ' | ||
- | |||
- | #tex += '< | ||
- | module = k.split()[0] | ||
- | pyfile = moduleToFile(module) | ||
- | if not(os.path.isfile(pyfile)): | ||
- | pyfile='' | ||
- | resfile = os.path.abspath(module.replace(' | ||
- | if not(os.path.isfile(resfile)): | ||
- | resfile = '' | ||
- | if (trueDiff): | ||
- | tex += ' | ||
- | tex += ' | ||
- | tex += '</ | ||
- | tex += '</ | ||
- | tex += '</ | ||
- | return (tex, len(sk)) | ||
- | |||
- | def generate(self): | ||
- | self.battery.setPaths() | ||
- | |||
- | print("' | ||
- | html1=self.htmlhead() | ||
- | html2 = '< | ||
- | html2+='< | ||
- | html2+='< | ||
- | html2+= '< | ||
- | html2+='< | ||
- | html2+='< | ||
- | html3 = "" | ||
- | html4 = '< | ||
- | html4 += ' | ||
- | html4 += ' | ||
- | for c in self.codes : | ||
- | if c not in self.battery.excludeCodesDiffs: | ||
- | fname = ' | ||
- | print(" | ||
- | |||
- | # (using " | ||
- | #import difflib | ||
- | #srcname = ' | ||
- | #srclines = open(srcname, | ||
- | #flines = open(fname, ' | ||
- | #diff = difflib.unified_diff(srclines, | ||
- | |||
- | #cmd = 'svn diff %s' % fname | ||
- | fname_dir, fname_base = os.path.split(fname) | ||
- | cwd = os.getcwd() | ||
- | os.chdir(fname_dir) | ||
- | if isUnix(): | ||
- | cmd = 'git diff HEAD -- %s' % fname_base | ||
- | else: | ||
- | cmd = 'git diff --ignore-cr-at-eol HEAD -- %s' % fname_base | ||
- | child = os.popen(cmd) | ||
- | diff = child.read() | ||
- | err = child.close() | ||
- | if err: | ||
- | print(' | ||
- | os.chdir(cwd) | ||
- | |||
- | tex, nb = self.diffOneCode(fname, | ||
- | if nb>0: | ||
- | html3 += tex | ||
- | html2 += '< | ||
- | html1 += ' | ||
- | if( c == " | ||
- | html1 += ' | ||
- | else: | ||
- | html1 += ' | ||
- | html1 += ' | ||
- | html1 += ' | ||
- | html4 += ' | ||
- | else: | ||
- | html2 += '< | ||
- | |||
- | html1 += " | ||
- | html2 +='</ | ||
- | html3 += " | ||
- | html4 += '} ); \n</ | ||
- | html1 += html4 | ||
- | html1 += '</ | ||
- | | ||
- | if self.diffpart: | ||
- | fname = ' | ||
- | else : | ||
- | fname = ' | ||
- | print(" | ||
- | file = open(fname,' | ||
- | file.write(html1+html2+html3) | ||
- | file.close() | ||
- | |||
- | self.battery.resetPaths() | ||
- | |||
- | # ---------------------------------------------------------------------------------------- | ||
- | class DiffGeneratorTsc(object): | ||
- | def __init__(self, | ||
- | self.battery | ||
- | if codes : | ||
- | self.codes | ||
- | else : | ||
- | self.codes | ||
- | |||
- | def htmlhead(self): | ||
- | global head | ||
- | return head % (machineid(), | ||
- | |||
- | |||
- | def generate(self): | ||
- | self.battery.setPaths() | ||
- | |||
- | diffs = {} | ||
- | for code in self.battery.codes : | ||
- | diffs[code]=[] | ||
- | |||
- | for mod in self.battery.loopOn(self.battery.dirs): | ||
- | bt = BatTest(self.battery, | ||
- | modDiffs = bt.diffTSC() | ||
- | for code in self.battery.codes : | ||
- | if code in modDiffs: | ||
- | diffs[code].extend(modDiffs[code]) | ||
- | |||
- | print("' | ||
- | html1=self.htmlhead() | ||
- | html2 = '< | ||
- | html2+='< | ||
- | html2+='< | ||
- | html2+= '< | ||
- | html2+='< | ||
- | html2+='< | ||
- | html3 = "" | ||
- | html4 = '< | ||
- | html4 += ' | ||
- | html4 += ' | ||
- | |||
- | for code in self.battery.codes : | ||
- | nb = len(diffs[code]) | ||
- | if nb > 0: | ||
- | html2 += '< | ||
- | |||
- | html3 += '< | ||
- | html3 += '< | ||
- | if(code == " | ||
- | html3 += ' | ||
- | else: | ||
- | html3 += ' | ||
- | # | ||
- | for d in sorted(diffs[code], | ||
- | if len(d) > 0: | ||
- | html3 += ' | ||
- | html3 += ' | ||
- | html3 += '</ | ||
- | html3 += '</ | ||
- | html3 += '</ | ||
- | |||
- | html1 += ' | ||
- | if( code == " | ||
- | html1 += ' | ||
- | else: | ||
- | html1 += ' | ||
- | html1 += ' | ||
- | html1 += ' | ||
- | html4 += ' | ||
- | else: | ||
- | html2 += '< | ||
- | |||
- | html1 += " | ||
- | html2 +='</ | ||
- | html3 += " | ||
- | html4 += '} ); \n</ | ||
- | html1 += html4 | ||
- | html1 += '</ | ||
- | # ecriture du fichier | ||
- | fname = ' | ||
- | print(" | ||
- | file = open(fname,' | ||
- | file.write(html1+html2+html3) | ||
- | file.close() | ||
- | |||
- | self.battery.resetPaths() | ||
- | # ---------------------------------------------------------------------------------------- | ||
- | |||
- | class WorkerThread(threading.Thread): | ||
- | """ | ||
- | A worker thread reading and executing a task queue filled by the main thread | ||
- | """ | ||
- | def __init__(self, | ||
- | threading.Thread.__init__(self) | ||
- | self.battery = battery | ||
- | self.num = num | ||
- | self.queue = queue | ||
- | # | ||
- | self.test=None | ||
- | |||
- | def write(self, string): | ||
- | writelock.acquire() | ||
- | setColor(thcolors[self.num%len(thcolors)]) | ||
- | sys.stdout.write(" | ||
- | resetColor() | ||
- | writelock.release() | ||
- | |||
- | def run(self): | ||
- | self.write(" | ||
- | while True: | ||
- | cmd, file = self.queue.get() | ||
- | if cmd == ' | ||
- | self.queue.task_done() | ||
- | break | ||
- | try: | ||
- | self.runFile(cmd, | ||
- | except (Exception, KeyboardInterrupt) as e: | ||
- | self.write(" | ||
- | writelock.acquire() | ||
- | traceback.print_exc() | ||
- | writelock.release() | ||
- | self.battery.errorEvent.set() # signale au main qu'il y a eu une couille | ||
- | if not self.queue.empty(): | ||
- | cmd, file = self.queue.get() # libere le main thread | ||
- | self.queue.task_done() | ||
- | break | ||
- | self.queue.task_done() | ||
- | self.write(" | ||
- | |||
- | def runFile(self, | ||
- | self.test = BatTest(self.battery, | ||
- | if cmd==' | ||
- | self.test.cleanModule() | ||
- | elif cmd==' | ||
- | self.test.runModule() | ||
- | if self.battery.buildTsc: | ||
- | self.test.buildTSCFile() | ||
- | elif cmd==' | ||
- | self.test.cleanModule() | ||
- | self.test.runModule() | ||
- | if self.battery.buildTsc: | ||
- | self.test.buildTSCFile() | ||
- | self.test=None | ||
- | |||
- | |||
- | # def kill(self): | ||
- | # print " | ||
- | # if self.test and self.test.pid: | ||
- | # print " | ||
- | # import ctypes | ||
- | # PROCESS_TERMINATE = 1 | ||
- | # handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, | ||
- | # ctypes.windll.kernel32.TerminateProcess(handle, | ||
- | # ctypes.windll.kernel32.CloseHandle(handle) | ||
- | # print " | ||
- | # ---------------------------------------------------------------------------------------- | ||
- | class Battery(object): | ||
- | """ | ||
- | Main class managing a test battery | ||
- | """ | ||
- | def __init__(self): | ||
- | """ | ||
- | feel free to modify public variables to modify the battery behavior | ||
- | """ | ||
- | # default dirs | ||
- | self.dirs = ' | ||
- | # verif dirs | ||
- | self.verifsrc = None | ||
- | self.verifdir = ' | ||
- | self.buildTsc = False | ||
- | # metafor dir | ||
- | self.mtfdir = ' | ||
- | # Working Dir Root | ||
- | self.wDRoot = '' | ||
- | # modules to be run by " | ||
- | self.cplx_exec = [ ] | ||
- | # modules to be run by " | ||
- | self.cplx_import = [ ] | ||
- | # modules to be run by in parallel (TBB/Blas) (one at a time) | ||
- | self.parallel = [ ] | ||
- | # modules to be run by restart (for launch & launchGui) | ||
- | self.restart = [] | ||
- | self.restartStepNo = -1 | ||
- | # result codes | ||
- | self.codes = [ ' | ||
- | self.excludeCodesDiffs = [ ] | ||
- | # platform specific | ||
- | self.skips = [ ' | ||
- | self.skipdirs = [ ' | ||
- | # global options | ||
- | self.useFPE | ||
- | self.withWER | ||
- | self.keepFacs = True | ||
- | # parallel parameters | ||
- | self.numTasks | ||
- | self.numThreads | ||
- | # cmd | ||
- | self.nice | ||
- | self.affinity | ||
- | if isUnix(): | ||
- | self.startCmd = [] | ||
- | else: | ||
- | self.startCmd = [' | ||
- | # threads related parms | ||
- | self.queue | ||
- | self.threads | ||
- | self.errorEvent | ||
- | self.python | ||
- | #series management (chaining tests) | ||
- | self.lasts=None | ||
- | |||
- | def useDebug(self): | ||
- | if not isUnix(): | ||
- | self.python = sys.executable.replace(' | ||
- | |||
- | def getSubprocessFlags(self): | ||
- | if self.withWER | ||
- | subProcessFlags = 0 | ||
- | else : | ||
- | import ctypes | ||
- | SEM_NOGPFAULTERRORBOX = 0x0002 # From MSDN | ||
- | ctypes.windll.kernel32.SetErrorMode(SEM_NOGPFAULTERRORBOX); | ||
- | CREATE_NO_WINDOW = 0x08000000 | ||
- | subProcessFlags = CREATE_NO_WINDOW | ||
- | return subProcessFlags | ||
- | |||
- | def write(self, string): | ||
- | writelock.acquire() | ||
- | sys.stdout.write(" | ||
- | writelock.release() | ||
- | |||
- | def addCplxExecPath(self, | ||
- | mod = fileToModule(path) | ||
- | print(" | ||
- | print(" | ||
- | print(" | ||
- | self.cplx_exec.append(mod) | ||
- | print(" | ||
- | def addCplxImportPath(self, | ||
- | mod = fileToModule(path) | ||
- | print(" | ||
- | print(" | ||
- | print(" | ||
- | self.cplx_import.append(mod) | ||
- | print(" | ||
- | def addParallelPath(self, | ||
- | mod = fileToModule(path) | ||
- | print(" | ||
- | print(" | ||
- | print(" | ||
- | self.parallel.append(mod) | ||
- | print(" | ||
- | def addRestartPath(self, | ||
- | mod = fileToModule(path) | ||
- | print(" | ||
- | print(" | ||
- | print(" | ||
- | self.restart.append(mod) | ||
- | print(" | ||
- | def setRestartStepNo(self, | ||
- | self.restartStepNo = no | ||
- | def setWDRoot(self, | ||
- | self.wDRoot = wd | ||
- | def setNumThreads(self, | ||
- | self.numThreads = num | ||
- | def setNumTasks(self, | ||
- | self.numTasks = num | ||
- | def setNice(self, | ||
- | if isUnix(): | ||
- | self.nice = [' | ||
- | else: | ||
- | if niceVal > 14 : | ||
- | prior = '/ | ||
- | elif niceVal > 8 : | ||
- | prior = '/ | ||
- | elif niceVal > 4 : | ||
- | prior = '/ | ||
- | elif niceVal > 2 : | ||
- | prior = '/ | ||
- | else: | ||
- | prior = '/ | ||
- | #self.nice = [' | ||
- | self.nice = [prior] | ||
- | print(" | ||
- | print(" | ||
- | |||
- | def setAffinity(self, | ||
- | if isUnix(): | ||
- | if self.hasSysCmd(' | ||
- | self.affinity = [ " | ||
- | elif self.hasSysCmd(' | ||
- | self.affinity = [ " | ||
- | else: | ||
- | print(" | ||
- | else: | ||
- | self.affinity = [] # to do according to doc below ... | ||
- | print(" | ||
- | # | ||
- | # | ||
- | ''' | ||
- | NODE Specifies the preferred Non-Uniform Memory Architecture (NUMA) | ||
- | node as a decimal integer. | ||
- | AFFINITY | ||
- | The process is restricted to running on these processors. | ||
- | |||
- | The affinity mask is interpreted differently when /AFFINITY and | ||
- | /NODE are combined. | ||
- | node's processor mask is right shifted to begin at bit zero. | ||
- | The process is restricted to running on those processors in | ||
- | common between the specified affinity mask and the NUMA node. | ||
- | If no processors are in common, the process is restricted to | ||
- | running on the specified NUMA node. | ||
- | |||
- | Specifying /NODE allows processes to be created in a way that leverages memory | ||
- | locality on NUMA systems. | ||
- | each other heavily through shared memory can be created to share the same | ||
- | preferred NUMA node in order to minimize memory latencies. | ||
- | memory from the same NUMA node when possible, and they are free to run on | ||
- | processors outside the specified node. | ||
- | |||
- | start /NODE 1 application1.exe | ||
- | start /NODE 1 application2.exe | ||
- | |||
- | These two processes can be further constrained to run on specific processors | ||
- | within the same NUMA node. In the following example, application1 runs on the | ||
- | low-order two processors of the node, while application2 runs on the next two | ||
- | processors of the node. This example assumes the specified node has at least | ||
- | four logical processors. | ||
- | node number for that computer without having to change the affinity mask. | ||
- | |||
- | start /NODE 1 /AFFINITY 0x3 application1.exe | ||
- | start /NODE 1 /AFFINITY 0xc application2.exe | ||
- | ''' | ||
- | |||
- | |||
- | def runFileMT(self, | ||
- | if self.numTasks> | ||
- | #print '[0] %s %s => queue' % (cmd, file) | ||
- | self.queue.put( (cmd,file) ) | ||
- | |||
- | if self.errorEvent.isSet(): | ||
- | raise Exception(" | ||
- | else: | ||
- | # single-threaded run | ||
- | t = WorkerThread(self) | ||
- | t.runFile(cmd, | ||
- | |||
- | def setPaths(self): | ||
- | self.old_sys_path = sys.path | ||
- | if ' | ||
- | self.old_os_environ = os.environ[' | ||
- | else: | ||
- | self.old_os_environ = '' | ||
- | |||
- | # needed by python for this script to behave like metafor | ||
- | self.mtfdir = os.path.abspath(self.mtfdir) | ||
- | if os.path.isdir(self.mtfdir): | ||
- | sys.path.append(os.path.abspath(self.mtfdir)) | ||
- | # needed by spawned python (e.g. ' | ||
- | os.environ[' | ||
- | else: | ||
- | self.write(" | ||
- | sys.exit() | ||
- | # adds nda modules | ||
- | ndadir = os.path.abspath(os.path.join(self.mtfdir, | ||
- | #print ndadir | ||
- | if os.path.isdir(ndadir): | ||
- | sys.path.append(ndadir) | ||
- | def resetPaths(self): | ||
- | sys.path = self.old_sys_path | ||
- | os.environ[' | ||
- | def isAParallelModule(self, | ||
- | mod = fileToModule(file) | ||
- | isParallel = False | ||
- | for mods in self.parallel : | ||
- | if mod.find(mods)!=-1: | ||
- | isParallel = True | ||
- | break | ||
- | return isParallel | ||
- | def start(self, cmd): | ||
- | """ | ||
- | multithreaded execution of the commands : clean, run, rerun | ||
- | """ | ||
- | self.setPaths() | ||
- | # generation of wDirRoot to avoid race between tasks in mt | ||
- | if self.wDRoot != '' | ||
- | createAndCheckDir(self.wDRoot) # function of pyutils | ||
- | # runs // : | ||
- | try: | ||
- | #print "main loop tests //\n" | ||
- | # main loop tests // (run en nbtasks = 1) | ||
- | print(" | ||
- | numThreads = self.numThreads # backup nbThreads | ||
- | numTasks | ||
- | # | ||
- | self.numThreads = numTasks | ||
- | for mod in self.loopOn(self.dirs): | ||
- | if self.isAParallelModule(mod) : | ||
- | #print (" | ||
- | # | ||
- | t = WorkerThread(self) | ||
- | t.runFile(cmd, | ||
- | self.numThreads = numThreads # recover nbThreads | ||
- | # | ||
- | print(" | ||
- | except (Exception, KeyboardInterrupt) as e: | ||
- | # abnormal termination (sig-break, syntax error in this file) | ||
- | self.write(" | ||
- | writelock.acquire() | ||
- | traceback.print_exc() | ||
- | writelock.release() | ||
- | sys.exit() | ||
- | self.lasts = None # Il est necessaire de reinitialiser cet attribut suite a la premiere boucle sur les modules pour les tests paralleles. | ||
- | # Dans le cas contraire, les tests series ci-dessous sont skippes dans le cas du run d'un et seul module par enchainement (et a fortiori avec launch.py). | ||
- | # | ||
- | # runs serie : | ||
- | # starts the threads | ||
- | if self.numTasks> | ||
- | self.errorEvent.clear() | ||
- | self.queue = queue.Queue(self.numTasks) | ||
- | for t in range(self.numTasks): | ||
- | tr = WorkerThread(self, | ||
- | self.threads.append(tr) | ||
- | tr.start() | ||
- | try: | ||
- | # main loop tests serie | ||
- | #print "main loop tests serie\n" | ||
- | #print " | ||
- | print(" | ||
- | for mod in self.loopOn(self.dirs): | ||
- | #print "mod : ",mod | ||
- | if not self.isAParallelModule(mod) : | ||
- | #print " | ||
- | self.runFileMT(cmd, | ||
- | # normal termination... stops the threads | ||
- | if self.numTasks> | ||
- | self.write(" | ||
- | for t in self.threads: | ||
- | self.queue.put( (' | ||
- | # waits for the threads | ||
- | for t in self.threads: | ||
- | t.join() | ||
- | print(" | ||
- | except (Exception, KeyboardInterrupt) as e: | ||
- | # abnormal termination (sig-break, syntax error in this file) | ||
- | self.write(" | ||
- | writelock.acquire() | ||
- | traceback.print_exc() | ||
- | writelock.release() | ||
- | if self.numTasks> | ||
- | self.write(" | ||
- | for t in self.threads: | ||
- | t.join() | ||
- | sys.exit() | ||
- | |||
- | self.resetPaths() | ||
- | |||
- | def loopOn(self, | ||
- | """ | ||
- | loop on the modules and | ||
- | - convert modules to paths ( intelSig.tests => ..\oo_nda\intelSig\tests) | ||
- | - expand dos wildcards | ||
- | """ | ||
- | modules.sort() | ||
- | #print " | ||
- | for dir in modules: | ||
- | #print " | ||
- | dir = dir.replace('/', | ||
- | |||
- | if dir.find(os.sep)!=-1 or fnmatch.fnmatch(dir,' | ||
- | # case #1: " | ||
- | filemod = os.path.abspath(dir) | ||
- | else: | ||
- | # case #2: " | ||
- | filemod = moduleToFile(dir) # avoids " | ||
- | if filemod=='': | ||
- | self.write(" | ||
- | sys.exit() | ||
- | |||
- | elif filemod.find(' | ||
- | # case #3: " | ||
- | #print " | ||
- | files=glob.glob(filemod) | ||
- | files.sort() | ||
- | for file in files: | ||
- | for mod in self.loopOn([file, | ||
- | yield mod | ||
- | elif os.path.isdir(filemod): | ||
- | # c'est un dir | ||
- | # case #4: " | ||
- | good=True | ||
- | for sk in self.skipdirs: | ||
- | if fnmatch.fnmatch(os.path.basename(filemod), | ||
- | good=False | ||
- | break | ||
- | if good: | ||
- | files = os.listdir(filemod) | ||
- | files.sort() | ||
- | for file in files: | ||
- | fullfile = os.path.join(filemod, | ||
- | for mod in self.loopOn([fullfile, | ||
- | yield mod | ||
- | else: | ||
- | # c'est un simple fichier | ||
- | #print " | ||
- | good=False | ||
- | if fnmatch.fnmatch(filemod,' | ||
- | good=True | ||
- | for sk in self.skips: | ||
- | if fnmatch.fnmatch(os.path.basename(filemod), | ||
- | good=False | ||
- | break | ||
- | if good: | ||
- | # teste si c'est une serie (tests par enchainement) | ||
- | reg1=r" | ||
- | exp1= re.compile(reg1) | ||
- | m = exp1.match(os.path.basename(filemod)) | ||
- | if m: # c'est potentiellement une serie | ||
- | #print " | ||
- | #print " | ||
- | if not m.group(1)==self.lasts: | ||
- | self.lasts = m.group(1) | ||
- | toyield = " | ||
- | #print " | ||
- | yield toyield | ||
- | else: # c'en est pas une | ||
- | #print " | ||
- | yield filemod | ||
- | |||
- | def verif(self): | ||
- | self.setPaths() | ||
- | ofiles = {} | ||
- | self.write(" | ||
- | |||
- | # new: create local verifdir is needed | ||
- | # if self.verifsrc and os.path.isdir(self.verifsrc): | ||
- | # if os.path.isdir(self.verifdir): | ||
- | # shutil.rmtree(self.verifdir, | ||
- | # if os.path.isdir(self.verifdir): | ||
- | # self.write(" | ||
- | # sleep(1) | ||
- | # shutil.copytree(self.verifsrc, | ||
- | if not os.path.isdir(self.verifdir): | ||
- | os.mkdir(self.verifdir) | ||
- | |||
- | # open files | ||
- | for c in self.codes: | ||
- | fname = ' | ||
- | ofiles[c] = open(fname, ' | ||
- | |||
- | for files in self.loopOn(self.dirs): | ||
- | gfiles=glob.glob(files) | ||
- | gfiles.sort() | ||
- | for file in gfiles: # peut etre une serie | ||
- | module = fileToModule(file, | ||
- | t = BatTest(self, | ||
- | tscs = t.verifModule() | ||
- | if len(tscs) == 0: | ||
- | ofiles[' | ||
- | else: | ||
- | for c in self.codes: | ||
- | for tsc in tscs: | ||
- | if tsc.find(' | ||
- | ofiles[c].write(" | ||
- | self.resetPaths() | ||
- | |||
- | def buildTscFiles(self): | ||
- | self.write(" | ||
- | for files in self.loopOn(self.dirs): | ||
- | gfiles=glob.glob(files) | ||
- | gfiles.sort() | ||
- | for file in gfiles: # peut etre une serie | ||
- | module = fileToModule(file, | ||
- | t = BatTest(self, | ||
- | t.buildTSCFile() | ||
- | # --- | ||
- | def handleRemoveReadonly(func, | ||
- | import stat | ||
- | # | ||
- | if not os.access(path, | ||
- | # Is the error an access error ? | ||
- | os.chmod(path, | ||
- | func(path) | ||
- | else: | ||
- | raise | ||
- | # --- | ||
- | def machineid(): | ||
- | uname = platform.uname() | ||
- | if uname[0] == ' | ||
- | return " | ||
- | elif uname[0] == ' | ||
- | if uname[4] == ' | ||
- | return " | ||
- | elif uname[4] == ' | ||
- | return " | ||
- | else: | ||
- | return " | ||
- | else: | ||
- | return uname[0] | ||
- | |||
- | def compilerid(): | ||
- | from wrap.mtGlobalw import getCompilerName | ||
- | name=getCompilerName() | ||
- | if name[: | ||
- | return name | ||
- | |||
- | # --- gestion sig-break | ||
- | |||
- | # lors d'un CTRL-BREAK: | ||
- | # windows: | ||
- | # single-thread: | ||
- | # multi-threads: | ||
- | # | ||
- | # il est necessaire de debloquer la queue pour que le main thread appelle le signal handler | ||
- | # linux: sig-break marche pas => Ctrl-C | ||
- | # single-thread: | ||
- | # multi-threads: | ||
- | # les autres threads sortent de Popen via FATAL_ERROR de Metafor => continuent! | ||
- | |||
- | class SigBreak(Exception): | ||
- | def __init__(self): | ||
- | self.msg=" | ||
- | def __str__(self): | ||
- | return self.msg | ||
- | |||
- | def sigbreak(sig, | ||
- | writelock.acquire() | ||
- | setColor(fg_red) | ||
- | print(" | ||
- | setColor(fg_dark_white) | ||
- | writelock.release() | ||
- | raise SigBreak() | ||
- | |||
- | # -- MAIN -- | ||
- | |||
- | def moduleToFile(module): | ||
- | for p in sys.path: | ||
- | #print ' | ||
- | dir = os.path.join(p, | ||
- | dirini = os.path.join(dir, | ||
- | file = ' | ||
- | #print ' | ||
- | if os.path.isfile(dirini): | ||
- | return dir | ||
- | elif os.path.isfile(file): | ||
- | return file | ||
- | return '' | ||
- | |||
- | def fileToModule(file, | ||
- | if verb: print(' | ||
- | file=os.path.abspath(file) | ||
- | if verb: print(' | ||
- | for dirname in sys.path: | ||
- | dirname = os.path.abspath(dirname).lower() | ||
- | if verb: print(' | ||
- | common = os.path.commonprefix( (file.lower(), | ||
- | if common == dirname: | ||
- | if verb: print(' | ||
- | strip = file[len(dirname): | ||
- | if strip[0]==os.path.sep: | ||
- | strip=strip[1: | ||
- | strip = os.path.splitext(strip)[0] | ||
- | strip = strip.replace(os.path.sep,' | ||
- | if verb: print(' | ||
- | return strip | ||
- | break | ||
- | else: | ||
- | if verb: print(' | ||
- | return '' | ||
- | |||
- | def main(battery=Battery()): | ||
- | |||
- | # trap ctrl-break (doesn t work with GUI) | ||
- | # note: only main thread catchs the signals | ||
- | try: | ||
- | import signal | ||
- | signal.signal(signal.SIGBREAK, | ||
- | # | ||
- | except: | ||
- | pass | ||
- | |||
- | import argparse | ||
- | parser = argparse.ArgumentParser(description=" | ||
- | |||
- | # Commandes | ||
- | cmdHelp = [] | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | cmdHelp.append(' | ||
- | # cmd parser | ||
- | parser.add_argument(' | ||
- | nargs='?', | ||
- | |||
- | parser.add_argument(' | ||
- | |||
- | # Options | ||
- | parser.add_argument(' | ||
- | help=' | ||
- | |||
- | parser.add_argument(' | ||
- | help=" | ||
- | parser.add_argument(' | ||
- | help=" | ||
- | |||
- | parser.add_argument(' | ||
- | help=' | ||
- | parser.add_argument(' | ||
- | help=' | ||
- | |||
- | parser.add_argument(' | ||
- | help=' | ||
- | parser.add_argument(' | ||
- | | ||
- | parser.add_argument(' | ||
- | | ||
- | |||
- | parser.add_argument(' | ||
- | | ||
- | parser.add_argument(' | ||
- | | ||
- | |||
- | parser.add_argument(' | ||
- | choices=[' | ||
- | help=' | ||
- | |||
- | # difficulte a passer la liste => laisse a l' | ||
- | # | ||
- | # | ||
- | # Parsing arguments | ||
- | print(sys.argv) | ||
- | args = parser.parse_args() | ||
- | #print " | ||
- | #print " | ||
- | # configure battery according to args | ||
- | if args.keepFacs : | ||
- | battery.keepFacs | ||
- | if args.fpe: | ||
- | battery.useFPE = True | ||
- | if args.withWER: | ||
- | battery.withWER = True | ||
- | if args.debug: | ||
- | battery.useDebug() | ||
- | if args.niceVal : | ||
- | battery.setNice(args.niceVal) | ||
- | if args.nbTasks: | ||
- | battery.setNumTasks(args.nbTasks) | ||
- | if args.nbThreads: | ||
- | battery.setNumThreads(args.nbThreads) | ||
- | # choosing defining modules to run | ||
- | if args.modules : | ||
- | battery.dirs = args.modules | ||
- | # WorkDir Root | ||
- | if args.wdroot: | ||
- | battery.setWDRoot(args.wdroot) | ||
- | # debug purpose | ||
- | print(args) | ||
- | # starting cmd | ||
- | if args.cmd in [' | ||
- | battery.start(args.cmd) | ||
- | elif args.cmd == ' | ||
- | battery.verif() | ||
- | elif args.cmd == ' | ||
- | battery.buildTscFiles() | ||
- | elif args.cmd == ' | ||
- | if args.codes : | ||
- | diff = DiffGenerator(battery, | ||
- | else : | ||
- | diff = DiffGenerator(battery, | ||
- | diff.generate() | ||
- | elif args.cmd == ' | ||
- | diff = DiffGenerator(battery, | ||
- | diff.generate() | ||
- | elif args.cmd == ' | ||
- | diff = DiffGeneratorTsc(battery, | ||
- | diff.generate() | ||
- | else : # par defaut | ||
- | battery.start(' | ||
- | battery.verif() | ||
- | |||
- | </ |
doc/user/tutorials/test_python.1599573968.txt.gz · Last modified: by boman