1 #@ MODIF test_fichier_ops Macro DATE 07/04/2009 AUTEUR COURTOIS M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2004 EDF R&D WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
9 # (AT YOUR OPTION) ANY LATER VERSION.
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
18 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
26 #-------------------------------------------------------------------------------
27 class TestFichierError(Exception):
30 #-------------------------------------------------------------------------------
34 def f_SOMM(somme, lx):
35 return somme + sum([convert(x) for x in lx])
37 def f_SOMM_ABS(somme, lx):
38 return somme + sum([abs(convert(x)) for x in lx])
41 return min(val, min([convert(x) for x in lx]))
44 return max(val, max([convert(x) for x in lx]))
46 def f_MINI_ABS(val, lx):
47 return min(val, min([abs(convert(x)) for x in lx]))
49 def f_MAXI_ABS(val, lx):
50 return max(val, max([abs(convert(x)) for x in lx]))
54 'SOMM_ABS' : f_SOMM_ABS,
57 'MINI_ABS' : f_MINI_ABS,
58 'MAXI_ABS' : f_MAXI_ABS,
61 #-------------------------------------------------------------------------------
62 def test_fichier_ops(self, FICHIER, NB_VALE, VALE, VALE_K, TYPE_TEST,
63 CRITERE, PRECISION, INFO, **kwargs):
65 Macro permettant de tester la non-regression d'un fichier.
66 On teste le nombre de réels présents, et, facultativement, la
67 somme de ces nombres et le texte du fichier.
70 # La macro compte pour 1 dans la numerotation des commandes
73 # On importe les definitions des commandes a utiliser dans la macro
74 # Le nom de la variable doit etre obligatoirement le nom de la commande
75 INFO_EXEC_ASTER = self.get_cmd('INFO_EXEC_ASTER')
76 DETRUIRE = self.get_cmd('DETRUIRE')
77 CREA_TABLE = self.get_cmd('CREA_TABLE')
78 TEST_TABLE = self.get_cmd('TEST_TABLE')
82 from Utilitai.Utmess import UTMESS
86 # vérifier que le fichier a été fermé
87 tinfo__ = INFO_EXEC_ASTER(LISTE_INFO='ETAT_UNITE', FICHIER=FICHIER)
88 if tinfo__['ETAT_UNITE', 1].find('OUVERT') > -1:
89 UTMESS('S','TEST0_2',valk=FICHIER)
92 if not os.path.isfile(FICHIER):
93 UTMESS('S', 'TEST0_3', valk=FICHIER)
94 fileobj = open(FICHIER, 'r')
96 # filtre par expression régulière
98 fileobj = regexp_filter(fileobj, kwargs['EXPR_IGNORE'])
99 except TestFichierError, (idmess, valk):
100 UTMESS('S', idmess, valk=valk)
102 # calcule le nombre de réels et la somme ou min/max
103 nbval, valeur, md5sum = test_iter(fileobj, function=dict_func_test[TYPE_TEST], verbose=(INFO > 1))
106 # produit le TEST_TABLE
107 md5ref = VALE_K or 'non testé'
108 is_ok = int(md5sum == md5ref)
109 tab1__ = CREA_TABLE(LISTE=(_F(PARA='NBVAL', LISTE_I=nbval,),
110 _F(PARA='VALEUR', LISTE_R=valeur,),
111 _F(PARA='TEXTE', LISTE_I=is_ok),),)
113 sVALE = '%20.13e' % VALE
116 UTMESS('I', 'TEST0_4', vali=(nbval, NB_VALE), valr=valeur, valk=(md5sum, md5ref, FICHIER, sVALE))
118 kwopt = { 'REFERENCE' : kwargs['REFERENCE'], }
119 if kwargs['REFERENCE'] == 'NON_REGRESSION':
120 kwopt['VERSION'] = kwargs['VERSION']
122 TEST_TABLE(TABLE=tab1__,
130 TEST_TABLE(TABLE=tab1__,
138 TEST_TABLE(TABLE=tab1__,
145 DETRUIRE(CONCEPT=_F(NOM=('tinfo__','tab1__'),),
146 ALARME='NON',INFO=1,)
149 #-------------------------------------------------------------------------------
150 def regexp_filter(file_in, regexp_ignore, debug=False):
151 """Filtre le fichier fourni (file descriptor) en utilisant les
152 expressions régulières fournies.
153 On retourne l'objet file vers le fichier modifié (ou non).
155 if not regexp_ignore: # None or []
157 # vérification des expressions régulières
158 if type(regexp_ignore) not in (list, tuple):
159 regexp_ignore = [regexp_ignore,]
161 for exp in regexp_ignore:
163 obj = re.compile(exp)
165 raise TestFichierError, ('TEST0_1', (s, str(exp)))
169 file_out = os.tmpfile()
171 for i, line in enumerate(file_in):
179 print ' >>>>>>>>>> IGNOREE <<<<<<<<<<'
189 #-------------------------------------------------------------------------------
190 re_float_expo = re.compile('[-+]?[0-9\.]+[eED][\-\+]{0,1}[0-9]+')
191 re_float = re.compile('[-+]?[0-9]+?\.[0-9]*')
192 re_int = re.compile('[0-9]+')
194 re_fortran = re.compile('([0-9]+)[dD]([\-\+]{0,1}[0-9]+)')
196 #-------------------------------------------------------------------------------
197 def test_iter(obj, function, verbose=False):
199 Cette fonction compte le nombre de réels dans le fichier et une grandeur
200 à partir des valeurs (somme, sommes des valeurs absolues, min/max...).
202 obj : objet 'file' ou 'string' sur le lequel on peut itérer
203 function : fonction de test val = func_test(val, [xi, ...])
204 verbose : on affiche le résumé si info>0
206 nombre de valeurs, valeur résultat
213 # Si on lit tout le fichier d'un coup, on va environ 3 fois plus vite
214 # que si on le lit ligne à ligne, mais on consomme en mémoire environ
215 # 5 fois la taille du fichier...
216 # En lisant par paquet de 1000 (ou 10000), on va quasiment aussi vite
217 # en consommant très peu de mémoire.
219 # fichier tout ligne/ligne 1000 lignes
221 # 50 Mo 17 s 48 s 17 s
222 # 100 Mo 34 s 96 s 35 s
224 # l'itérateur est l'objet file lui-même ou on le crée sur la liste
225 if type(obj) is file:
235 text = iterator.next()
236 except StopIteration:
240 if ok and len(buff) < max_buff_size:
246 l_float = re_float_expo.findall(text)
247 l_float = [s.replace('D', 'E') for s in l_float]
248 text = re_float_expo.sub('', text)
249 l_float.extend(re_float.findall(text))
250 text = re_float.sub('', text)
251 l_float.extend( re_int.findall(text))
252 text = re_int.sub('', text)
254 nbval += len(l_float)
255 val = function(val, l_float)
257 text = ''.join([s.strip() for s in text.split()])
261 print 'Nombres réels et entiers :'
266 md5sum = md5text.hexdigest()
268 return nbval, val, md5sum
270 #-------------------------------------------------------------------------------
271 def test_file(filename, regexp_ignore=[], type_test='SOMM', verbose=False):
272 """Raccourci pour tester rapidement un fichier (utilisé par stanley.py).
274 if type(regexp_ignore) not in (list, tuple):
275 regexp_ignore = [regexp_ignore,]
277 fileobj = open(filename, 'r')
278 fileobj = regexp_filter(fileobj, regexp_ignore)
280 nbv, val, md5sum = test_iter(fileobj, function=dict_func_test[type_test], verbose=verbose)
282 return nbv, val, md5sum
284 #-------------------------------------------------------------------------------
285 if __name__ == '__main__':
286 from optparse import OptionParser, OptionGroup
288 p = OptionParser(usage='usage: %s fichier [options]' % sys.argv[0])
289 p.add_option('--type_test',
290 action='store', dest='type_test', default='SOMM',
291 help='type du test : SOMM, SOMM_ABS, MIN, MAX')
292 p.add_option('--expr_ignore',
293 action='store', dest='exp', type='string',
294 help='expression régulière à ignorer')
295 p.add_option('-v', '--verbose',
296 action='store_true', dest='verbose', default=False,
298 opts, args = p.parse_args()
301 p.error('fichier à tester ?')
308 fileobj = open(args[0], 'r')
309 fileobj = regexp_filter(fileobj, exp)
310 nbv2, sumv2, md5sum2 = test_iter(fileobj, function=dict_func_test[opts.type_test], verbose=opts.verbose)
311 print '%6d valeurs, resultat = %f, texte : %s' % (nbv2, sumv2, md5sum2)