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
